hdu3033 分组背包(每组最少选一个)

题意:

Iserlohn 要买运动鞋,商店总共有N双运动鞋,他总共有M元钱,这些运动鞋分为K类,每类都有自己的编号i,每类中的每双鞋有单价m,和Iserlohn对这双鞋的评价价值v。Iserlohn想每一类运动鞋至少买一双,在不超过他所拥有的总金额前提下,使他得到的v最大。

http://acm.hdu.edu.cn/showproblem.php?pid=3033

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <cstring>
 5 using namespace std;
 6 const int Ni = 12;
 7 struct node{
 8     int m,val;
 9 };
10 int dp[Ni][10010];
11 int main()
12 {
13     int n,tval,kind,i,j,k;
14     while(~scanf("%d%d%d",&n,&tval,&kind))
15     {
16         vector<node> sneak[Ni];
17         for(i=1;i<=n;i++)
18         {
19             node s;
20             scanf("%d%d%d",&j,&s.m,&s.val);
21             sneak[j].push_back(s);
22         }
23         bool flg=0;
24         for(i=1;i<=kind;i++)
25         {
26             if(sneak[i].size()==0)
27             {
28                 flg=1;
29                 printf("Impossible\n");
30                 break;
31             }
32         }
33         if(flg) continue;
34         memset(dp,-1,sizeof(dp));
35         for(i=0;i<=tval;i++) dp[0][i]=0;
36         for(i=1;i<=kind;i++)
37         {
38             for(j=0;j<sneak[i].size();j++)
39             {
40                 for(k=tval;k>=sneak[i][j].m;k--)
41                 {
42                     if(dp[i][k-sneak[i][j].m]!=-1)
43                     dp[i][k]=max(dp[i][k],dp[i][k-sneak[i][j].m]+sneak[i][j].val);
44                     //位置不能换,如第二组数据
45                     if(dp[i-1][k-sneak[i][j].m]!=-1)
46                     dp[i][k]=max(dp[i][k],dp[i-1][k-sneak[i][j].m]+sneak[i][j].val);
47                 }
48             }
49         }
50         if(dp[kind][tval]==-1) printf("Impossible\n");
51         else printf("%d\n",dp[kind][tval]);
52     }
53     return 0;
54 }
55 /*
56 3 5 3
57 1 2 5
58 2 2 1
59 3 2 2
60 
61 3 5 3
62 1 0 5
63 2 0 1
64 3 0 2
65 
66 3 5 3
67 1 0 0
68 2 0 0
69 3 0 0
70 */
原文地址:https://www.cnblogs.com/qijinbiao/p/2635847.html