描述:
现有n个物体和容量为V的背包,每个物体i都有对应的重量w[i]和价值v[i],每个物体最多拿一次,在所取物体总重量不超过V的情况下,能获得的最大价值是多少?
分析
- 每个物体只有拿和不拿两种情况,则在选择是否拿第i件时,在之前已确定部分的基础上进行比较判断即可
- 申请一个二维数组dp[][],用dp[i][j]来表示在物品数量为i,总重量为j的条件下能达到的最大价值,那么dp[i][j]的值为:最后dp[n][V]即为答案
Code
1 | for(int i=1;i<=n;i++) |
优化
- 前面的代码在时间复杂度上已经无法继续优化,但是在空间复杂度上,因为我们只需要最多取n个的答案,所以我们可以在dp[i][j]的基础上去掉物体数这一维,那么dp[j]的值就为:
Code
1 | for(int i=1;i<=n;i++) |
注意
- 在遍历重量的时候是V->w[i],并不是w[i]->V,其原因是:第i个物体的状态只与i-1有关,我们在操作dp[j]的时候必须保证dp[j-w[i]]是上一次操作后的结果,如果从w[i]->V,那么dp[j-w[i]]的值在操作dp[j]之前就已经发生了改变,里面存的不是i-1时刻的值
- 数组dp的值要全部初始化为0