HDU 3033 I love sneakers! (分组背包)

来源:互联网 发布:微信无法连接网络 编辑:程序博客网 时间:2024/06/13 03:36

HDU题目链接

该题和背包九讲中的分组背包还是有区别的,九讲中每组取一个,这题每组随意取,因此循环顺序变一下,相当于在每组中有个0-1背包就可以了

代码中带解释:

import java.util.Arrays;import java.util.Scanner;public class Main{static Scanner sc = new Scanner(System.in);static int [][] dp=new int[11][10005];static int [] v=new int[105];static int [] w=new int[105];static int [] k=new int[105];static int n,m,b;public static void main(String[] args) {while(sc.hasNext()) {n=sc.nextInt();m=sc.nextInt();b=sc.nextInt();for(int i=1;i<=n;i++) {k[i]=sc.nextInt();w[i]=sc.nextInt();v[i]=sc.nextInt();}//因为价格可能等于0,所以初始化为-1,否则无法判断该状态是由于价格导致的0还是没买导致的0for(int i=1;i<=10;i++) {Arrays.fill(dp[i], -1);}for(int i=1;i<=b;i++) {for(int j=1;j<=n;j++) {  if(k[j]==i) {   //find brand 'i'for(int t=m;t>=w[j];t--) { //0-1 bag//A.当w[j]=0时,//1.dp[i][t]=Math.max(dp[i][t], dp[i][t]+v[j])-->dp[i][t]=dp[i][t]+v[j]//2.dp[i][t]=Math.max(dp[i][t], dp[i-1][t]+v[j]);//此时的dp[i][t]就是上面的dp[i][t]+v[j],它必不可能小于dp[i-1][t]+v[j],因此这个顺序没问题//如果相反//1.dp[i][t]=Math.max(dp[i][t], dp[i-1][t]+v[j])-->dp[i][t]=dp[i-1][t]+v[j]//2.dp[i][t]=Math.max(dp[i][t], dp[i][t-w[j]]+v[j])//此时的dp[i][t]是上面的dp[i-1][t]+v[j],它有可能小于dp[i][t]+v[j]//那么这种时候,就会有dp[i][t]=dp[i-1][t]+v[j]+v[j]//即这双鞋被买了两次,不可取,所以两个判断的顺序不能换。//B.判断是否为-1的原因是,如果该状态是-1,则表示,在它之前的几种状态必有一种品牌没买,不符合题意if(dp[i][t-w[j]]!=-1)// same group and valid dp[i][t]=Math.max(dp[i][t], dp[i][t-w[j]]+v[j]);if(dp[i-1][t-w[j]]!=-1)//front group and validdp[i][t]=Math.max(dp[i][t], dp[i-1][t-w[j]]+v[j]);}}}}if(dp[b][m]>0)System.out.println(dp[b][m]);elseSystem.out.println("Impossible");}System.exit(0);}}