01背包与完全背包问题
动态规划是刷题过程中的常见算法,有难有易,简单的如斐波那契数列问题很容易找到规律,难一些的就很容易钻牛角尖了,而背包问题又是动态规划的一个典型问题,这里就拿比较典型的01背包与完全背包问题做一下记录。
01背包问题
01背包问题题目要求
- 有N件物品和一个容量为V的背包
- 第i件物品的体积是Vi,其价值是Wi
- 每件物品只能使用一次
- 要求物品体积不超过背包容量且价值最大
理清楚思路就容易理解了。用到了两层for循环,外层是依次循环每个物品,内层是背包容积,依次去计算当前容积下的最大价值,后续的计算可以依赖前边的计算,完成算法。
1 | /** |
但是这样用到了一个二维数组,空间复杂度较高,有没有可能通过一维数组实现呢?
01背包问题空间复杂度优化
关键点只有一个,容积要逆序循环保证不会重复使用物品
1 | /** |
完全背包问题
01背包问题题目要求
- 有N件物品和一个容量为V的背包
- 第i件物品的体积是Vi,其价值是Wi
- 每件物品可以无限次使用
- 要求物品体积不超过背包容量且价值最大
01背包与完全背包的区别是,完全背包中每个物品都是可以无限次使用的。
其解法与01背包的一维数组方式也是基本一致的,只需要注意容积是正序循环的,因为可以重复使用物品
1 | /** |
总结
0-1背包二维数组解法:
核心计算公式是dp[i][j] = max(dp[i-1][j],dp[i-1][j-c[i]]+w[i])
参与计算的是dp[i-1]所以每个物品是只用过一次的
0-1背包一维数组解法:
核心计算公式是dp[j] = max(dp[j],dp[j-c[i]]+w[i])
因为是逆序进行的,背包容量从大往小算,刚开始的时候小容积的价值还没有计算当前物品,所以不会重复使用
完全背包:
核心计算公式dp[j] = max(dp[j],dp[j-c[i]]+w[i]),与01背包一致。
区别在于正序进行的过程中是可以对同一物品多次使用的。