算法-生活中的动态规划及实现
package main import ( fmt ) // // 动态规划常见题型 Go 实现合集 // // 通用思路 // 1. 定义状态 dp[...] 表示什么 // 2. 找状态转移方程 // 3. 确定初始化 // 4. 确定遍历顺序 // 5. 返回最终答案 // // ------------------------------------------------------------ // 1. 爬楼梯 Climbing Stairs // // 题目每次可以走 1 阶或 2 阶走到第 n 阶有多少种方法 // // 状态dp[i] 到达第 i 阶的方法数 // 转移dp[i] dp[i-1] dp[i-2] // 初始化dp[1] 1, dp[2] 2 // 时间复杂度O(n) // 空间复杂度O(n) // ------------------------------------------------------------ func climbStairs(n int) int { if n 2 { return n } dp : make([]int, n1) dp[1] 1 dp[2] 2 for i : 3; i n; i { dp[i] dp[i-1] dp[i-2] } return dp[n] } // 爬楼梯空间优化版 // 因为 dp[i] 只依赖 dp[i-1] 和 dp[i-2] // 所以不需要保存整个数组。 // 空间复杂度O(1) func climbStairsOptimized(n int) int { if n 2 { return n } a, b : 1, 2 for i : 3; i n; i { a, b b, ab } return b } // ------------------------------------------------------------ // 2. 打家劫舍 House Robber // // 题目相邻房屋不能同时偷求最大收益。 // // 状态dp[i] 偷到第 i 间房时前 i1 间房的最大收益 // // 当前房屋有两种选择 // 1. 不偷dp[i-1] // 2. 偷dp[i-2] nums[i] // // 转移dp[i] max(dp[i-1], dp[i-2] nums[i]) // // 时间复杂度O(n) // 空间复杂度O(n) // ------------------------------------------------------------ func rob(nums []int) int { n : len(nums) if n 0 { return 0 } if n 1 { return nums[0] } dp : make([]int, n) dp[0] nums[0] dp[1] max(nums[0], nums[1]) for i : 2; i n; i { dp[i] max( dp[i-1], // 不偷当前房屋 dp[i-2]nums[i], // 偷当前房屋 ) } return dp[n-1] } // 打家劫舍空间优化版 func robOptimized(nums []int) int { prev2 : 0 prev1 : 0 for _, money : range nums { current : max( prev1, // 不偷 prev2money, // 偷 ) prev2 prev1 prev1 current } return prev1 } // ------------------------------------------------------------ // 3. 不同路径 Unique Paths // // 题目机器人从左上角走到右下角只能向右或向下 // 一共有多少条路径 // // 状态dp[i][j] 到达位置 (i,j) 的路径数量 // // 当前位置只能来自 // 1. 上方 (i-1,j) // 2. 左方 (i,j-1) // // 转移dp[i][j] dp[i-1][j] dp[i][j-1] // // 时间复杂度O(m*n) // 空间复杂度O(m*n) // ------------------------------------------------------------ func uniquePaths(m int, n int) int { dp : make([][]int, m) for i : 0; i m; i { dp[i] make([]int, n) } // 第一列只有一种走法一直向下 for i : 0; i m; i { dp[i][0] 1 } // 第一行只有一种走法一直向右 for j : 0; j n; j { dp[0][j] 1 } for i : 1; i m; i { for j : 1; j n; j { dp[i][j] dp[i-1][j] dp[i][j-1] } } return dp[m-1][n-1] } // ------------------------------------------------------------ // 4. 0/1 背包 // // 题目每个物品只能选一次。 // weights[i] 为重量values[i] 为价值capacity 为背包容量。 // // 状态dp[c] 容量为 c 时可获得的最大价值 // // 对于一个重量 w、价值 v 的物品 // dp[c] max(dp[c], dp[c-w] v) // // 关键容量必须从大到小遍历。 // 原因防止一个物品被重复使用。 // // 时间复杂度O(n*capacity) // 空间复杂度O(capacity) // ------------------------------------------------------------ func zeroOneKnapsack(weights []int, values []int, capacity int) int { dp : make([]int, capacity1) for i : 0; i len(weights); i { w : weights[i] v : values[i] // 0/1 背包必须倒序 for c : capacity; c w; c-- { dp[c] max( dp[c], dp[c-w]v, ) } } return dp[capacity] } // ------------------------------------------------------------ // 5. 零钱兑换 Coin Change // // 题目给定若干硬币面值每种硬币可以无限使用。 // 求凑出 amount 的最少硬币数。 // // 状态dp[x] 凑出金额 x 所需要的最少硬币数 // // 如果最后使用一枚 coin // dp[x] min(dp[x], dp[x-coin] 1) // // 初始化 // dp[0] 0 // 其他值初始化为一个很大的数 // // 时间复杂度O(amount * len(coins)) // 空间复杂度O(amount) // ------------------------------------------------------------ func coinChange(coins []int, amount int) int { const INF int(^uint(0)1) / 2 dp : make([]int, amount1) for i : 1; i amount; i { dp[i] INF } dp[0] 0 for x : 1; x amount; x { for _, coin : range coins { if x coin dp[x-coin] ! INF { dp[x] min( dp[x], dp[x-coin]1, ) } } } if dp[amount] INF { return -1 } return dp[amount] } // ------------------------------------------------------------ // 6. 最长递增子序列 LIS // // 题目求数组中的最长严格递增子序列长度。 // // 例如 // nums [10,9,2,5,3,7,101,18] // 答案 4 // 例如子序列 [2,3,7,101] // // 状态dp[i] 以 nums[i] 结尾的最长递增子序列长度 // // 如果 j i 且 nums[j] nums[i] // 那么 nums[i] 可以接在 nums[j] 后面 // // dp[i] max(dp[i], dp[j] 1) // // 时间复杂度O(n^2) // 空间复杂度O(n) // ------------------------------------------------------------ func lengthOfLIS(nums []int) int { if len(nums) 0 { return 0 } n : len(nums) dp : make([]int, n) answer : 1 for i : 0; i n; i { dp[i] 1 for j : 0; j i; j { if nums[j] nums[i] { dp[i] max( dp[i], dp[j]1, ) } } answer max(answer, dp[i]) } return answer } // ------------------------------------------------------------ // 7. 最长公共子序列 LCS // // 题目求两个字符串的最长公共子序列长度。 // // 状态 // dp[i][j] text1 前 i 个字符与 text2 前 j 个字符 // 的最长公共子序列长度。 // // 如果当前字符相同 // dp[i][j] dp[i-1][j-1] 1 // // 如果当前字符不同 // dp[i][j] max(dp[i-1][j], dp[i][j-1]) // // 时间复杂度O(m*n) // 空间复杂度O(m*n) // ------------------------------------------------------------ func longestCommonSubsequence(text1 string, text2 string) int { m : len(text1) n : len(text2) dp : make([][]int, m1) for i : 0; i m; i { dp[i] make([]int, n1) } for i : 1; i m; i { for j : 1; j n; j { if text1[i-1] text2[j-1] { dp[i][j] dp[i-1][j-1] 1 } else { dp[i][j] max( dp[i-1][j], dp[i][j-1], ) } } } return dp[m][n] } // ------------------------------------------------------------ // 工具函数 // ------------------------------------------------------------ func max(a int, b int) int { if a b { return a } return b } func min(a int, b int) int { if a b { return a } return b } // ------------------------------------------------------------ // 示例运行 // ------------------------------------------------------------ func main() { fmt.Println( 动态规划 Go 示例 ) // 1. 爬楼梯 fmt.Println(\n1. 爬楼梯) fmt.Println(n 5) fmt.Println(答案:, climbStairs(5)) fmt.Println(空间优化答案:, climbStairsOptimized(5)) // 2. 打家劫舍 fmt.Println(\n2. 打家劫舍) houses : []int{2, 7, 9, 3, 1} fmt.Println(房屋金额:, houses) fmt.Println(最大收益:, rob(houses)) fmt.Println(空间优化答案:, robOptimized(houses)) // 3. 不同路径 fmt.Println(\n3. 不同路径) fmt.Println(3 x 3 网格) fmt.Println(路径数量:, uniquePaths(3, 3)) // 4. 0/1 背包 fmt.Println(\n4. 0/1 背包) weights : []int{1, 3, 4} values : []int{15, 20, 30} capacity : 4 fmt.Println(weights:, weights) fmt.Println(values :, values) fmt.Println(capacity:, capacity) fmt.Println(最大价值:, zeroOneKnapsack(weights, values, capacity)) // 5. 零钱兑换 fmt.Println(\n5. 零钱兑换) coins : []int{1, 2, 5} amount : 11 fmt.Println(coins:, coins) fmt.Println(amount:, amount) fmt.Println(最少硬币数:, coinChange(coins, amount)) // 6. LIS fmt.Println(\n6. 最长递增子序列 LIS) nums : []int{10, 9, 2, 5, 3, 7, 101, 18} fmt.Println(nums:, nums) fmt.Println(LIS 长度:, lengthOfLIS(nums)) // 7. LCS fmt.Println(\n7. 最长公共子序列 LCS) text1 : abcde text2 : ace fmt.Println(text1:, text1) fmt.Println(text2:, text2) fmt.Println(LCS 长度:, longestCommonSubsequence(text1, text2)) }

相关新闻

Python基础语法练习题(51-52)

Python基础语法练习题(51-52)

今天接着来记录两个基础语法练习题。第五十一题,时间处理:#编写一个程序,使用time模块来实现时间处理功能#导入time模块,用于处理时间相关的任务import time#获取当前时间的时间戳,即自1970-01-01 00:00:00以来的秒数c…

2026/10/8 6:49:48 阅读更多 →
我把印象笔记的「加密导出」掰开揉碎,最后用一招绕过了它——本地明文库直提全攻略

我把印象笔记的「加密导出」掰开揉碎,最后用一招绕过了它——本地明文库直提全攻略

我把印象笔记的「加密导出」掰开揉碎,最后用一招绕过了它——本地明文库直提全攻略一次真实的自救:7 个 .notes 文件、7.7GB、正文全是密文。本文记录从逆向加密格式到最终 601 条笔记无损导出的全过程,包括每一步的踩坑、调试和验证方法。脚…

2026/10/8 6:48:48 阅读更多 →
在Word中快速实现同类内容应用“双行合一”格式

在Word中快速实现同类内容应用“双行合一”格式

最近在将金瓶梅词话HTML版改编成带目录与页眉且支持交叉链接的Word文档过程中&#xff0c;想将其中的批注处理成双行合一格式。书中共有三种批注&#xff1a;眉批、侧批、夹批。HTML代码分别是下面这几种形式&#xff1a;眉批&#xff1a;<span class"comment top-comm…

2026/10/8 6:48:48 阅读更多 →

最新新闻

Python ai-html-parse 包实战案例与常见错误

Python ai-html-parse 包实战案例与常见错误

1. 引言在 Python 爬虫与数据清洗领域&#xff0c;解析 HTML 是绕不开的核心环节。虽然 BeautifulSoup、lxml 等老牌库功能强大&#xff0c;但面对结构复杂、属性繁多的现代网页&#xff0c;开发者往往需要编写大量样板代码。ai-html-parse 正是为解决这一痛点而生的新一代 HTM…

2026/10/9 14:05:07 阅读更多 →
DAY7 CSS184-196

DAY7 CSS184-196

DAY1→HTML1-29 DAY2→HTML29-53 DAY3→HTML&CSS53-79 DAY4→CSS79-108 DAY5→CSS108-133 DAY6→CSS133-147&182-183 61.伸缩盒模型 &#xff08;一&#xff09;简介 &#xff08;1&#xff09;轻松控制元素分布方式&#xff0c;元素对齐方式&#xff0c;元素视觉顺序…

2026/10/9 14:05:07 阅读更多 →
Oracle 11g实例脚本运行全攻略:从环境配置到排错调优

Oracle 11g实例脚本运行全攻略:从环境配置到排错调优

简介&#xff1a;《Oracle 11g从入门到精通&#xff08;第二版&#xff09;》实例源程序包&#xff0c;面向Oracle初学者与需要系统提升数据库技能的开发、运维人员&#xff0c;覆盖19个章节的配套代码&#xff0c;帮助读者通过动手实践理解数据存储、查询优化、事务处理及备份…

2026/10/9 14:05:07 阅读更多 →
数据库课设实战:学生体质健康管理系统SQL建模与查询优化

数据库课设实战:学生体质健康管理系统SQL建模与查询优化

简介&#xff1a;这是一套面向计算机相关专业学生的数据库课程设计完整交付包&#xff0c;以学生体质健康管理系统为选题&#xff0c;适合作为期末大作业、课程设计或毕业设计的参考范例&#xff0c;也便于初学者通过实战理解数据库设计与应用开发的完整流程。压缩包共包含5个文…

2026/10/9 14:05:07 阅读更多 →
斐波那契数列从兔子问题到1000内列表:四种解法与工程实践

斐波那契数列从兔子问题到1000内列表:四种解法与工程实践

1. 从一对兔子说起&#xff1a;斐波那契数列到底在描述什么很多人第一次听到“斐波那契数列”这五个字&#xff0c;脑子里冒出来的是一串冷冰冰的数字&#xff1a;1、1、2、3、5、8、13、21……然后就是无穷无尽的递推公式和编程题。但如果你真的回到这个数列被提出的原始场景&…

2026/10/9 14:05:07 阅读更多 →
计算机毕设项目4:基于springboot+uniapp自习室预约小程序(含AI智能预约+候补转正+座位AI协商)

计算机毕设项目4:基于springboot+uniapp自习室预约小程序(含AI智能预约+候补转正+座位AI协商)

所有项目已经整理完毕&#xff0c;后续的还在整理。更多项目&#xff0c;请联系我。 更多项目可以看&#xff1a;2026全新计算机毕设选题&#xff08;小众&#xff0c;含创新点&#xff09;-CSDN博客 所有成品和定制&#xff0c;均先免费部署&#xff0c;不需要定jin&#xff…

2026/10/9 14:04:07 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题&#xff0c;隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题&#xff0c;排查到最后发现是ZonedDateTime序列化后时区丢了&#xff0c;用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问&#xff1a;办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好&#xff0c;问题是工作场景经常要在几处环境之间来回切换&#xff0c;每次都先登录跳板机再层层代理&#xff0c;实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及&#xff0c;但真正动手搭过一套能跑起来的 Agent 系统的人都知道&#xff0c;从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地&#xff0c;从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →