dp-01背包

01背包问题是动态规划中的一个经典问题,通常用于解决资源分配问题。问题描述如下:

假设有一个背包,其最大承重为 W) n ) 个物品,每个物品有一个重量 wi) v_i )。目标是选择一些物品放入背包,使得在不超过背包承重的前提下,背包中物品的总价值最大。

问题特点

  • 01性质:每个物品要么选择放入背包(1),要么不放入背包(0),不能选择部分放入或多次放入。

动态规划解法

动态规划(Dynamic Programming, DP)是解决01背包问题的常用方法。我们可以通过构建一个二维数组 dp) dp[i][j] ) 表示前 i) j ) 的情况下可以获得的最大价值。

状态转移方程

  • 如果不选择第 i) dp[i][j] = dp[i-1][j] )。
  • 如果选择第 i) dp[i][j] = dp[i-1][j-w_i] + v_i ),前提是 $ j geq w_i )。

因此,状态转移方程可以写成:
[ dp[i][j] = max(dp[i-1][j], dp[i-1][j-w_i] + v_i) ]

初始化

  • dp[0][j]=0 表示没有物品时,无论背包容量是多少,最大价值都是0。
  • dp[i][0]=0 表示背包容量为0时,无论有多少物品,最大价值都是0。

填表过程

i=1nj=0W 依次填表,最终 dp[n][W] 就是所求的最大价值。

空间优化

由于每次计算 dp[i][j]只依赖于dp[i1][j]dp[i1][jwi],因此可以将二维数组优化为一维数组。优化后的状态转移方程为:
[dp[j]=max(dp[j],dp[j-w_i]+v_i)]

需要注意的是,在更新dp[j])j)需要从W)w_i),以保证每个物品只被选择一次。

代码实现

以下是01背包问题的Python代码实现:

def knapsack(W, weights, values):
    n = len(weights)
    dp = [0] * (W + 1)
    
    for i in range(n):
        for j in range(W, weights[i] - 1, -1):
            dp[j] = max(dp[j], dp[j - weights[i]] + values[i])
    
    return dp[W]

总结

01背包问题通过动态规划的方法,可以在多项式时间内解决。通过构建状态转移方程和优化空间复杂度,可以高效地求解背包问题。

posted @   mcr130102  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
请不要抄袭任何人的博客,这是对一名开发者最基本的尊重。
点击右上角即可分享
微信分享提示
想一个人有多想念,那又是文字失效瞬间。