Codeforces 741B-Arpa's weak amphitheater and Mehrdad's valuable Hoses

题意:给你一些人,然后每个人都有美貌值和重量,这些人有的是一组的,有的不是一组,舞台有一个最大的重量限制,让你求出最大的美貌值是多少。

思路:可以一组选一个,也可以直接选一组人。当时训练的时候感觉是一到dp,但是不知道怎么转移。听学长讲题以后,才知道是分组背包的个提醒,然后看了《背包九讲》里关于分组背包的内容,去hdu水了一道关于分组背包的(另外一篇博客里有)。然后这道题就是用并查集储存一下,然后用分组背包处理一下就可以了。

下面是AC代码(最开始写的时候一直不知道哪里错了,没办法输出,最后发现是并查集find写错了,太菜了orz!!):

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1010;
 4 int dp[maxn],be[maxn],we[maxn];
 5 int f[maxn];
 6 
 7 int Find(int x)
 8 {
 9     return f[x]==x?x:f[x]=Find(f[x]);
10 }
11 
12 void megre(int x,int y)
13 {
14     int t1=Find(x);
15     int t2=Find(y);
16     if(t1!=t2){
17         f[t1]=t2;
18     }
19 }
20 
21 int main()
22 {
23     int n,m,w;
24     while(~scanf("%d %d %d",&n,&m,&w))
25     {
26         for(int i=1;i<=n;i++)
27             scanf("%d",&we[i]);
28         for(int i=1;i<=n;i++)
29             scanf("%d",&be[i]);
30         for(int i=1;i<=n;i++)
31             f[i]=i;
32         for(int i=1;i<=m;i++){
33             int x,y;
34             scanf("%d %d",&x,&y);
35             megre(x,y);
36         }
37         vector<int>g[maxn];
38         for(int i=1;i<=n;i++)
39             g[Find(i)].push_back(i);
40         memset(dp,0,sizeof(dp));
41         for(int i=1;i<=n;i++){
42             if(Find(i)!=i) continue;
43             for(int j=w;j>=0;j--){
44                 int sum1=0,sum2=0;
45                 for(int k=0;k<g[i].size();k++){
46                     sum1+=we[g[i][k]];
47                     sum2+=be[g[i][k]];
48                     if(j>=we[g[i][k]])
49                         dp[j]=max(dp[j],dp[j-we[g[i][k]]]+be[g[i][k]]);
50                 }
51                 if(j>=sum1)
52                     dp[j]=max(dp[j],dp[j-sum1]+sum2);
53             }
54         }
55         printf("%d\n",dp[w]);
56     }
57     return 0;
58 }

 

posted @ 2017-07-22 12:51  啦啦啦天啦噜  阅读(338)  评论(0编辑  收藏  举报