解法+例题
动态规划的三个基本要素:
- 最优子结构
- 边界条件
- 状态转移方程
0-1背包
有N件物品和一个容量为V的背包。第i件物品的费用是w[i],价值是v[i],求将哪些物品装入背包可使价值总和最大。限定每个物品要么拿(1个)要么不拿(0个)
普通解法
用f[n,C]来表示将n个物品放入容量为C的背包可以得到的最大收益,第i个物品有拿与不拿两种情况,表示为:
状态转移方程
f[i][c] = max( f[i - 1][c], f[i - 1][c - w[i]] + v[i] )
代码
public static int knapSack(int[] w, int[] v, int C) {
int size = w.length;
if (size == 0) {
return 0;
}
int[][] dp = new int[size][C + 1];
//初始化第一行
//仅考虑容量为C的背包放第0个物品的情况
for (int i = 0; i <= C; i++) {
dp[0][i] = w[0] <= i ? v[0] : 0;
}
//填充其他行和列
//外循环:放入物品的数量;内循环:容量
for (int i = 1; i < size; i++) {
for (int j = 0; j <= C; j++) {
dp[i][j] = dp[i - 1][j];
if (w[i] <= j