题意 : 对于给定
n
个模特,每个模特有一个体重
思路:
如果不考虑最后的限制条件,这道题目是一道比较裸的01背包
加上限制条件,他同样是一个01背包。
我们首先用一个并查集来维护模特之间的朋友关系
之后我们统计每个圈子的模特的重量之和以及魅力值之和。
然后对于每个圈子,更新这个圈子里的所有模特的值,以及整个圈子的值
然后输出最大的
dp[i] #include <cstdio> #include <string> #include<iostream> #include<vector> #include <stack> #include <queue> #include <map> #include <cstdlib> #include<string.h> #include <cstring> #include <ctime> #include <algorithm> #include <set> using namespace std; typedef long long ll; typedef pair<int, int>pii; typedef pair<ll, ll> pll; typedef pair<int, ll> pil; typedef vector<vector<ll> >vvi; typedef vector<ll> vi; const ll mod = 1e9 + 7; const int MAXN = 1000; const int MAXM = 1000; int fa[1200]; ll but[1200]; ll dp[1200]; ll we[1200]; ll allbut[1200]; ll allwe[1200]; vector<int>g[1200]; int getfa(int x) { return x == fa[x] ? fa[x]:fa[x] = getfa(fa[x]); } int main() { for (int i = 0; i < 1200; i++)fa[i] = i; ll n, m, k; scanf("%I64d%I64d%I64d", &n, &m, &k); for (ll i = 1; i <= n; i++)scanf("%I64d", &we[i]); for (ll i = 1; i <= n; i++)scanf("%I64d", &but[i]); memset(dp, -1, sizeof dp); memset(allbut, 0, sizeof allbut); memset(allwe, 0, sizeof allwe); for (ll i = 0; i < m; i++) { int x, y; scanf("%d%d", &x, &y); int fx = getfa(x); int fy = getfa(y); fa[fx] = fy; } for (ll i = 1; i <= n; i++) g[getfa(i)].push_back(i), allwe[getfa(i)] += we[i], allbut[getfa(i)] += but[i]; dp[0] = 0; for (ll i = 1; i <= n; i++) { if (!g[i].size())continue; for (ll j = k; j >= 0; j--) { if (dp[j] == -1)continue; for (int l = 0; l< g[i].size(); l++) { if (j + we[g[i][l]] <= k)dp[j + we[g[i][l]]] = max(dp[j + we[g[i][l]]], dp[j] + but[g[i][l]]); } if (j + allwe[i] <= k)dp[j + allwe[i]] = max(dp[j + allwe[i]], dp[j] + allbut[i]); } } ll ans = -1; for (ll i = 0; i <= k; i++)ans = max(ans, dp[i]); cout << ans << endl; //system("pause"); }