[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
",ans);
53     }
54     return 0;
55 }
View Code
原文地址:https://www.cnblogs.com/MekakuCityActor/p/10747167.html