import java.util.Scanner; import java.util.*; //dp[i][j]表示从i个物品中选 //总体积不超过j的最大价值和 public class Main { static int N = 1010; static int n,V; //总数、总体积 static int[] v = new int[N]; //表示体积 static int[] w = new int[N]; //表示价值 static int[][] dp = new int[N][N]; public static void main(String[] args) { Scanner in = new Scanner(System.in); while (in.hasNextInt()) { n = in.nextInt(); V = in.nextInt(); //读入数据 ,从1开始读入,创建虚拟节点 for(int i=1;i<=n;i++){ v[i] = in.nextInt(); w[i] = in.nextInt(); } //1.解决第一问 //1.初始化,虚拟节点初始化为0即可 //2.填表 for(int i =1;i<=n;i++){ for(int j=1;j<=V;j++){ //1.不选第i个物品的价值 dp[i][j] = dp[i-1][j]; //价值与前一个相同 //2.选第i个物品价值,需要判断j-v[i] 是否还能装得下, //取两种情况最大值 if(j>=v[i]) dp[i][j] = Math.max(dp[i][j],dp[i-1][j-v[i]] +w[i]); } } System.out.println(dp[n][V]); //输出结果 //解决第二问,先清空dp表 for(int i=0;i<=n;i++){ for(int j=0;j<=V;j++){ dp[i][j] = 0; } } //1.初始化,上面的虚拟节点初始化为-1,因为不存在垓解 for(int i=1;i<=V;i++) dp[0][i] = -1; //2.填表 for(int i =1;i<=n;i++){ for(int j=1;j<=V;j++){ //1.不选第i个物品的价值 dp[i][j] = dp[i-1][j]; //价值与前一个相同 //2.选第i个物品价值,需要判断j-v[i] 是否还能装得下, //并且还要判断dp[i-1][j-v[i]] 是否有解 if(j>=v[i] &&dp[i-1][j-v[i]] !=-1) dp[i][j] = Math.max(dp[i][j],dp[i-1][j-v[i]] +w[i]); } } //输出第二问的解,需要判断是否存在 if(dp[n][V]==-1){ System.out.println(0); }else{ System.out.println(dp[n][V]); } } } }