zoukankan      html  css  js  c++  java
  • Codeforces 741B:Arpa's weak amphitheater and Mehrdad's valuable Hoses(01背包+并查集)

    http://codeforces.com/contest/741/problem/B

    题意:有 n 个人,每个人有一个花费 w[i] 和价值 b[i],给出 m 条边,代表第 i 和 j 个人是一个集合的,给出一个最大花费 w,如果一个集合的人不能同时选的话,那么只能选集合中的其中一个或者不选,问按照这样的规则选得的花费不超过 w 的最大价值是多少。

    思路:一开始搞个带权并查集出来,后来还是蒙了。之后看原来是01背包,然而已经N久没见过背包了。。。先用并查集弄出集合,然后对每个集合中的元素进行01背包(选集合中的一个或者不选的情况),在集合弄完之后还要对整体进行01背包(选集合中的全部),这里用了下滚动数组。

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstring>
     5 #include <string>
     6 #include <cmath>
     7 #include <queue>
     8 #include <vector>
     9 using namespace std;
    10 #define INF 0x3f3f3f3f
    11 #define N 100010
    12 int dp[2][1010];
    13 int fa[1010];
    14 int b[1010], w[1010];
    15 vector<int> vec[1010];
    16 
    17 int Find(int x) {
    18     if(x == fa[x]) return x;
    19     return fa[x] = Find(fa[x]);
    20 }
    21 
    22 int main()
    23 {
    24     int n, m, x;
    25     scanf("%d%d%d", &n, &m, &x);
    26     for(int i = 1; i <= n; i++) scanf("%d", w + i);
    27     for(int i = 1; i <= n; i++) scanf("%d", b + i);
    28     for(int i = 1; i <= n; i++) fa[i] = i;
    29     for(int i = 0; i < m; i++) {
    30         int u, v;
    31         scanf("%d%d", &u, &v);
    32         u = Find(u), v = Find(v);
    33         if(u != v) fa[u] = v;
    34     }
    35     for(int i = 1; i <= n; i++)
    36         vec[Find(i)].push_back(i);
    37     int now = 0;
    38     for(int i = 1; i <= n; i++) {
    39         now = !now;
    40         int ww = 0, bb = 0;
    41         for(int j = 0; j <= x; j++) dp[now][j] = dp[!now][j];
    42         for(int j = 0; j < vec[i].size(); j++) {
    43             int id = vec[i][j];
    44             int www = w[id], bbb = b[id];
    45             ww += www, bb += bbb;
    46             for(int j = www; j <= x; j++) { // 在当前集合选一个最优
    47                 dp[now][j] = max(dp[now][j], dp[!now][j-www] + bbb);
    48             }
    49         }
    50         for(int j = ww; j <= x; j++) { // 如果全部能丢进去
    51             dp[now][j] = max(dp[now][j], dp[!now][j-ww] + bb);
    52         }
    53     }
    54     int ans = 0;
    55     for(int i = 0; i <= x; i++) ans = max(ans, dp[now][i]);
    56     printf("%d
    ", ans);
    57     return 0;
    58 }
  • 相关阅读:
    配置高并发jdbc连接池
    java中的sleep()和wait()的区别
    程序员必知的8大排序(三)-------冒泡排序,快速排序(java实现)
    转HashMap Hashtable区别
    chrome 常用快捷操作
    sublime Text 常用操作
    flash 右键菜单隐藏与修改
    As3.0 视频缓冲、下载总结
    flash cs6 更新到Flash player15.0 及Air 更新方法
    As3.0 Interface 与类的使用
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6141048.html
Copyright © 2011-2022 走看看