import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
int V=scanner.nextInt();
int v[]=new int[n];
int w[]=new int[n];
for (int i = 0; i < w.length; i++) {
v[i]=scanner.nextInt();//体积
w[i]=scanner.nextInt();//价值
}
/*
* int dp[][]=new int[n][V+1];//dp[i][j]表示在体积为j的情况下,考虑是否装第i件物品,使得价值最大 //初始化 for
* (int i = 0; i < dp.length; i++) { dp[i][0]=0; } for (int j = 0; j < V+1; j++)
* { if(j>=v[0])dp[0][j]=w[0]; } for (int i = 1; i < n; i++) { for (int j = 1; j
* < V+1; j++) { if(j>=v[i]) { dp[i][j]=Math.max(dp[i-1][j-v[i]]+w[i],
* dp[i-1][j]); }else { dp[i][j]=dp[i-1][j]; }
*
* } } System.out.println(dp[n-1][V]);
*/
//不要求全部装满
int dp1[]=new int[V+1];
for (int i = 0; i < n ; i++) {
for (int j = V; j >= v[i]; j--) {
dp1[j]=Math.max(dp1[j], dp1[j-v[i]]+w[i]);
}
}
System.out.println(dp1[V]);
//下面计算要求背包恰好装满的最大价值
long dp2[]=new long[V+1];
Arrays.fill(dp2, -1);//负数表示无法恰好装满
dp2[0]=0;//初始化,容量为0肯定能装满
for (int i = 0; i < n; i++) {
for (int j = V; j >= v[i]; j--) {
if(dp2[j-v[i]]!=-1) {
dp2[j]=Math.max(dp2[j-v[i]]+w[i], dp2[j]);
}
}
}
if(dp2[V]!=-1) {
System.out.println(dp2[V]);
}else {
System.out.println(0);
}
}
}
01背包我之前只会二维dp版的,没想到还有一维dp优化版,首先讲一下不要求恰好装满的情况,我们创建一维dp1数组,dp1[j]表示在容量为j的情况下,能装的最大价值。dp1[j]=Math.max(dp1[j], dp1[j-v[i]]+w[i]);循环中j要求逆序,也就是i从V+1到v[i],这样才能保证后面的结果不会把前面的结果覆盖。
要求恰好装满的情况,我们先把dp2的所有元素赋为-1,然后把dp[0]赋值为0,因为当容量为0时,一定能恰好装满,且价值为0。后买如果dp2[j-v[i]]不等于-1,也就是那个容量下就已经能装满了,我现在恰好给它增加v[i]的容量,那肯定也可以装满v[i]



京公网安备 11010502036488号