动态规划背包问题
问题大多如下
- 一个背包总沉重固定为多少kg
- 有一堆物品,每个物品都有价格和重量
- 在不撑爆背包的情况下,能装走的最多物品的价格或者重量
例题如下
背包问题开的数组一般都和背包的总承重有关
题解:
- 对于每个物体,需要知道是否能拼出重量w([0,m])
- 对于最后一个物体,看它是否可以进入背包
- 如果除了最后一个物体,其他物体能拼出重量w,或者其他物体能拼出w-a[n-1],即最后一个物体拿与不拿的时候能拼出的重量.
- [0,m]中能拼出的最大重量即为能带走的最大重量
问题分析
- 算知道前n个物体能不能拼出w([0,m])//[0,m]用一个维度的数字表示
- 需要知道前n-1个物体能不能拼出w[0,m]
- 子问题
- dp[i][w] 表示前i个物体能否拼出w,w的取值为[0,m]
一种常见的错误分析方式
用dp[i]表示前i个物体能拼出的最大重量(不超过target,即背包的最大重量),dp[i+1]能拼出的最大重量为dp[i]+a[i],即前i个物体能拼出的最大重量加上当前物体的重量.
- [3,9,5,2] target=10;
- 前三个物体能拼出来的最大重量为9
- 前四个物体能拼出来的最大重量不是用前三个物体的最大重量+当前重量,9+2=11>target;而是3,5,2;所以不能用dp[i]去递推dp[i+1];两者不存在状态切换.
状态转移
dp[i][w] =dp[i-1][w] or dp[i-1][w-a[i]]
第二个表示:前i-1个物体能否装下除了当前的物体的重量.
第二个时候 w>=a[i]必须成立
初始条件 dp[0][0]=true; dp[0][1-m]=false;