[Tom and Bag][需要记录过程的dp]

http://acm.beihua.edu.cn/problem/1007

Tom and Bag
 

Description

 

Tom is the most handsome CCPC contestant in HIT.Tom got a bag recently. The bag has a volume V. Tom has n boxes of candy. He wants to fillthis bag with these boxes.Each box i has a value Ai, a volume Vi, and a color Ci.We define a bag’s beautiful level P as the number of different colors on boxes in this bag.Tom wants to make P not less than K to make the bag colorful.After that, Tom wants to make the sum of values of boxes in the bag maximum. The sum ofvolumes of boxes in the bag could not exceed V.It is guaranteed that Tom could use these n boxes to make the bag colorful.Tom wants you to help him calculate what’s the maximum sum of values his colorful bagcould carry.

 

Input

 

First line contains an integer T (1 ≤ T ≤ 5), represents there are T test cases.For each test case:The first line contains three integers N, K, V (1 ≤ N ≤ 100, 1 ≤ K ≤ 5, 1 ≤ V ≤200), represents there are N boxes, the number of colors could not be less than K, and the bag’svolume is V.Each line of the following N lines contains three integers Ai, Vi, Ci (1 ≤ Ai ≤ 1000, 1 ≤Vi ≤ V, 1 ≤ Ci ≤ N), represents the ith box’s value, volume and color.

 

Output

 

For each test case, output one line with an integer W, represents the maximum sum ofvalues.

 

Sample Input 1 

3
5 1 10
3 2 1
5 8 1
7 9 1
1 2 2
2 2 3
5 2 10
3 2 1
5 8 1
7 9 1
1 2 2
2 2 3
5 3 10
3 2 1
5 8 1
7 9 1
1 2 2
2 2 3

Sample Output 1

8
7
6

Hint

Tom will eat all candies couldn’t be filled into the bag. So don’tworry about wasting candies.

题意:有一个容量为v的背包,有n个物品,每种物品都有一个价值ai,一个体积 vi,一种颜色 ci,求放入背包的颜色数至少为k的背包最大价值

题解:比平常的背包就多了一个颜色的限制,可以通过按颜色排序,让颜色一样的在一块,dp[i][j][k]表示到第i种物品的时候已经有了j种颜色使用容积为k时的背包价值最大值,在dp更新的过程记录一下当前值是否是由该种颜色的值更新的,即分类更新一下使用颜色的那一维即可

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 int dp[105][105][205],flag[105][105][205];
 5 struct pot{
 6     int a;
 7     int va;
 8     int ca;
 9 }p[105];
10 bool cmp(struct pot aa,struct pot bb){
11     return aa.ca<bb.ca;
12 }
13 int main(){
14     int t;
15     scanf("%d",&t);
16     while(t--){
17         int n,k,v;
18         scanf("%d%d%d",&n,&k,&v);
19         for(int i=1;i<=n;i++){
20             scanf("%d%d%d",&p[i].a,&p[i].va,&p[i].ca);
21         }
22         sort(p+1,p+1+n,cmp);
23         int c=-1;
24         memset(dp,-1,sizeof(dp));
25         for(int i=0;i<=n;i++){
26             dp[i][0][0]=0;
27         }
28         int ans=0;
29         for(int i=1;i<=n;i++){
30             for(int j=0;j<=v;j++){
31                 for(int q=1;q<=n;q++){
32                     dp[i][q][j]=dp[i-1][q][j];
33                     flag[i][q][j]=flag[i-1][q][j];
34                     if(j-p[i].va>=0&&flag[i-1][q-1][j-p[i].va]!=p[i].ca){
35                         if(dp[i-1][q-1][j-p[i].va]!=-1&&dp[i-1][q-1][j-p[i].va]+p[i].a>=dp[i][q][j]){
36                             dp[i][q][j]=dp[i-1][q-1][j-p[i].va]+p[i].a;
37                             flag[i][q][j]=p[i].ca;
38                         }
39                     }
40                     if(j-p[i].va>=0&&flag[i-1][q][j-p[i].va]==p[i].ca){
41                         if(dp[i-1][q][j-p[i].va]!=-1&&dp[i-1][q][j-p[i].va]+p[i].a>=dp[i][q][j]){
42                             dp[i][q][j]=dp[i-1][q][j-p[i].va]+p[i].a;
43                             flag[i][q][j]=p[i].ca;
44                         }
45                     }
46                     if(q>=k){
47                         ans=max(ans,dp[i][q][j]);
48                     }
49                 }
50             }
51         }
52         printf("%d\n",ans);
53     }
54     return 0;
55 }
View Code

 

转载于:https://www.cnblogs.com/MekakuCityActor/p/10747167.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值