P1445搭配购买

一、题目描述

  

 

 二、题目分析

  看到这个题目的时候我就觉得这是一个有依赖的背包,可以用树形dp,但是我不会,就用并查集预处理+01背包就解决了

三、代码实现

 1 #include "bits/stdc++.h"
 2 using namespace std;
 3 int dp[11000];
 4 int a[11000],v[11000];
 5 int b[11000],v1[11000];
 6 int c[11000],bk[11000];
 7 int find(int u)
 8 {
 9     if(u == c[u])
10         return u;
11     return c[u] = find(c[u]);
12 }
13 int main()
14 {
15     int n,m,w;
16     cin >> n >> m >> w;
17     for(int i = 1;i <= 10000;i++)
18         c[i] = i;
19     for(int i = 1;i <= n;i++)
20         cin >> a[i] >> v[i];
21     int fx,fy;
22     for(int i = 1;i <= m;i++){
23         cin >> fx >> fy;
24         fx = find(fx);
25         fy = find(fy);
26         c[fy] = fx;
27     }
28 
29     int k = 1;
30     for(int i = 1;i <= n;i++){
31         if(bk[i] == 1)
32             continue;
33         int f = find(i);
34         b[k] =  a[i];
35         v1[k] = v[i];
36         bk[i] = 1;
37         for(int j = i + 1;j <= n;j++){
38             if(bk[j] != 1 && f == find(j)){
39                 bk[j] = 1;
40                 b[k] += a[j];
41                 v1[k] += v[j];
42             }
43         }
44         k++;
45     }
46 
47     //01背包k件物品
48     for(int i = 1;i < k;i++)
49         for(int j = w;j >= b[i];j--)
50             dp[j] = max(dp[j],dp[j - b[i]] + v1[i]);
51     cout << dp[w];
52     return 0;
53 }

 

posted @ 2022-01-20 20:09  scannerkk  阅读(34)  评论(0)    收藏  举报