在算法世界中,动态规划(Dynamic Programming)是一类非常强大且常用的技术,而背包问题则是动态规划中最经典、最常被引用的入门案例。本文将用通俗易懂的方式,手把手教你用 Go语言 实现01背包问题,即使你是编程小白,也能轻松理解!
想象你是一个小偷(别担心,只是假设 😅),你有一个容量有限的背包,面前有一堆物品,每个物品都有自己的重量和价值。你的目标是:在不超过背包容量的前提下,装入总价值最大的物品组合。
这就是经典的01背包问题——每个物品只能选择“拿”或“不拿”(0 或 1),不能分割。
暴力枚举所有组合的时间复杂度是 O(2ⁿ),当物品数量多时根本不可行。而动态规划通过记忆化子问题,将时间复杂度优化到 O(n × W),其中 n 是物品数量,W 是背包容量。
我们用二维 DP 表来讲解思路,再优化为一维数组提升空间效率。
设 dp[i][w] 表示前 i 个物品,在背包容量为 w 时能获得的最大价值。
对于第 i 个物品(重量为 weight[i-1],价值为 value[i-1]):
取两者最大值即可。
package mainimport "fmt"func knapsack(weights []int, values []int, capacity int) int { n := len(weights) // 创建二维DP表,初始化为0 dp := make([][]int, n+1) for i := range dp { dp[i] = make([]int, capacity+1) } // 填充DP表 for i := 1; i <= n; i++ { for w := 0; w <= capacity; w++ { // 不拿当前物品 dp[i][w] = dp[i-1][w] // 如果能拿,尝试拿 if w >= weights[i-1] { candidate := dp[i-1][w-weights[i-1]] + values[i-1] if candidate > dp[i][w] { dp[i][w] = candidate } } } } return dp[n][capacity]}func main() { weights := []int{2, 3, 4, 5} values := []int{3, 4, 5, 6} capacity := 8 result := knapsack(weights, values, capacity) fmt.Printf("最大价值为:%d\n", result) // 输出:10} 观察发现,dp[i][w] 只依赖于上一行 dp[i-1][...],因此可以用一维数组从后往前更新,节省空间。
func knapsackOptimized(weights []int, values []int, capacity int) int { dp := make([]int, capacity+1) for i := 0; i < len(weights); i++ { // 从后往前遍历,避免覆盖未更新的值 for w := capacity; w >= weights[i]; w-- { if dp[w] < dp[w-weights[i]] + values[i] { dp[w] = dp[w-weights[i]] + values[i] } } } return dp[capacity]} 通过本文,你应该已经掌握了如何用 Go 语言解决 01 背包问题。动态规划看似抽象,但只要理解“子问题”和“状态转移”的思想,就能迎刃而解。动手敲一遍代码,你会理解得更深刻!
提示:在实际面试或项目中,背包问题常作为算法基础考察点,建议反复练习并尝试变种题型。
本文由主机测评网于2025-12-10发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025125677.html