AcWing 3. 【Java】完全背包问题
原题链接
简单
作者:
tt2767
,
2020-01-12 00:00:14
,
所有人可见
,
阅读 1897
/*
1. 状态定义: 当已经选择1...i 个物品且容量 <=j时的最大价值 f[i][j] -> 优化为f[j]
2. 状态计算: 选择i ,不选i -> 优化为遍历所有可能的体积的最大值
3. f[~] = 0
*/
import java.util.*;
public class Main{
void run(){
int n = jin.nextInt();
int m = jin.nextInt();
for (int i = 1 ; i <= n ; i++){
v[i] = jin.nextInt();
w[i] = jin.nextInt();
}
int res = dp(n, m);
// int res = dp2(n, m);
System.out.println(res);
}
int dp(int n, int m){
int[] f= new int[maxN];
for (int i = 1 ; i <= n; i++){
for (int j = v[i]; j<= m ; j++){
// 计算了从0~m 的所有体积转移的可能结果,所以不用再每次枚举选第i个物品几个
// 直接对应了每个物品可选无限次
f[j] = Math.max(f[j], f[j-v[i]] + w[i]);
}
}
return f[m];
}
int dp2(int n , int m){
int[] f = new int[maxN];
for (int i = 1 ; i <= n ; i++){
for (int j = m ; j >= v[i] ; j--){
for (int k = 0 ;k * v[i] <= j ; k++){ // 转化为01 背包 + 无限选的做法
f[j] = Math.max(f[j], f[j-k*v[i]] + k*w[i]);
}
}
}
return f[m];
}
int maxN = 1002;
int[] v = new int[maxN];
int[] w = new int[maxN];
Scanner jin = new Scanner(System.in);
public static void main(String[] args) throws Exception {new Main().run();}
}
赞一个