• codeforces 742D Arpa's weak amphitheater and Mehrdad's valuable Hoses ——(01背包变形)


      题意:给你若干个集合,每个集合内的物品要么选任意一个,要么所有都选,求最后在背包能容纳的范围下最大的价值。

      分析:对于每个并查集,从上到下滚动维护即可,其实就是一个01背包= =。

      代码如下:

     1 #include <stdio.h>
     2 #include <algorithm>
     3 #include <string.h>
     4 #include <vector>
     5 using namespace std;
     6 const int N = 1000 + 5;
     7 
     8 int w[N],b[N];
     9 int n,m,W;
    10 int root[N];
    11 vector<int> v[N];
    12 int allw[N],allb[N];
    13 int dp[N];
    14 int find(int x) {return x == root[x] ? x : root[x] = find(root[x]);}
    15 
    16 int main()
    17 {
    18     scanf("%d%d%d",&n,&m,&W);
    19     for(int i=1;i<=n;i++) root[i] = i;
    20     for(int i=1;i<=n;i++) scanf("%d",w+i);
    21     for(int i=1;i<=n;i++) scanf("%d",b+i);
    22     for(int i=1;i<=m;i++)
    23     {
    24         int x,y;scanf("%d%d",&x,&y);
    25         int rx = find(x), ry = find(y);
    26         if(rx != ry) root[rx] = ry;
    27     }
    28     for(int i=1;i<=n;i++)
    29     {
    30         int t = find(i);
    31         v[t].push_back(i);
    32         allw[t] += w[i];
    33         allb[t] += b[i];
    34     }
    35     for(int i=1;i<=n;i++)
    36     {
    37         if(v[i].size() == 0) continue;
    38         for(int j=W;j>=0;j--)
    39         {
    40             for(int k=0;k<v[i].size();k++)
    41             {
    42                 if(j-w[v[i][k]] >= 0) dp[j] = max(dp[j], dp[j-w[v[i][k]]] + b[v[i][k]]);
    43             }
    44             if(j-allw[i] >= 0) dp[j] = max(dp[j], dp[j-allw[i]] + allb[i]);
    45         }
    46     }
    47     printf("%d
    ",dp[W]);
    48     return 0;
    49 }
  • 相关阅读:
    上传github代码
    git 代码更新
    linux 遇见的问题
    How to stop pycharm show files in project in red color?
    Linux下动态库查找路径的问题
    centos7 建立虚拟目录
    [BZOJ3747] Kinoman
    [BZOJ2169] 连边
    [洛谷P4251] 小凸玩矩阵
    [洛谷P2764] 最小路径覆盖
  • 原文地址:https://www.cnblogs.com/zzyDS/p/6190671.html
Copyright © 2020-2023  润新知