# 完全背包问题
在 01 背包基础上,每个物品可以取无数次
- 有 N 种物品和一个容量是 V 的背包,每种物品都有无限件可用。
- 第 i 种物品的体积是 vi,价值是 wi。
- 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。
- 输出最大价值。
dp[i]
表示总体积为i
的情况下的最大价值
代码模板
function maxValue(N, V, v, w) {
let dp = new Array(V + 1).fill(0);
for (let i = 0; i < N; i++) {
// 循环物品
for (let j = v[i]; j <= V; j++) {
// 循环体积;从小到大;跟01背包问题反过来,表示v[i]可以取多次
dp[j] = Math.max(dp[j], dp[j - v[i]] + w[i]);
}
}
return dp[V];
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 322. 零钱兑换 (opens new window)
求最少硬币数
class Solution {
public int coinChange(int[] coins, int V) {
int n = coins.length;
int []f = new int[V+1];
Arrays.fill(f, 0x3f3f3f3f);
f[0] = 0;
for (int i = 0; i < n; i++){
for (int v = coins[i]; v<= V; v++){
f[v] = Math.min(f[v], f[v-coins[i]]+1);
}
}
return f[V] == 0x3f3f3f3f?-1:f[V] ;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
拓展:如何打印出最少硬币数的方案?输出一种即可
# 518. 零钱兑换 II (opens new window)
求兑换的方案数
class Solution {
public int change(int V, int[] c) {
int dp[] = new int[V+1];
dp[0] = 1;
for (int x : c){
for (int v = x; v <=V; v++ ){
dp[v] += dp[v-x];
}
}
return dp[V];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13