<L> <K>
0 0
input | output |
---|---|
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0 |
5 |
没有上司的年会。ural要举办场年会,请你邀请来宾。要求每位客人的直接上司不被邀请,否则会很尴尬。每位客人有一个兴趣值。要求使来宾的兴趣值之和最大。
每个人可以选择去或者不去。所以:
dp[t][0] 表示以t为最高上司的子树不安排t参加的最大兴趣值。
dp[t][1] 表示以t为最高上司的子树安排t参加的最大兴趣值。
不安排t参加的话,其直系下属可以去或者不去。dp[t][0] = sum(max(dp[ti][0], dp[ti][1]));
安排t参加的话,其直系下属均不能参加。dp[t][1] = sum(dp[ti][0]) + c[t];
#include <cstdio> #include <vector> #include <cstring> #include <iostream> using namespace std; int n; int c[6006]; std::vector<int > v[6006]; int dp[6006][2]; void Tdp(int t) { if(v[t].size() == 0) { dp[t][0] = 0; dp[t][1] = c[t]; return ; } for (int i=0; i<v[t].size(); i++) { Tdp(v[t][i]); } for (int i=0; i<v[t].size(); i++) { dp[t][0] += max(dp[v[t][i]][0], dp[v[t][i]][1]); dp[t][1] += dp[v[t][i]][0]; } dp[t][1] += c[t]; } int main () { cin >> n; for (int i=1; i<=n; i++) { cin >> c[i] ; } int l ,k; int vis[6006]; memset(vis, false, sizeof(vis)); while (cin >> l >> k) { if (l == 0 && k == 0) break; v[k].push_back(l); vis[l] = true; } int root; for (int i=1; i<=n; i++) { if (!vis[i]) { root = i; break; } } Tdp(root); cout << max(dp[root][0], dp[root][1]) <<endl; return 0; }
原文:http://blog.csdn.net/xuelanghu407/article/details/43541569