博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 2342 Anniversary party 树形DP基础题
阅读量:5276 次
发布时间:2019-06-14

本文共 1515 字,大约阅读时间需要 5 分钟。

题目链接:

题目大意:在一个公司中,每个职员有一个快乐值ai,现在要开一个party,邀请了一个员工就不可能邀请其直属上司,同理邀请了一个人就不可以邀请其的直属员工,

问如何使得这个快乐值达到最大。

题解:对每个结点dp[i][0]表示不邀请这个员工,其子树达到的最大快乐值,dp[i][1]表示邀请i员工其子树达到的最大值。

dp[i][0]=(i的全部员工的max(dp[u][1],dp[u][0)相加,也就是其子员工来或不来的最大快乐值。
dp[i][1]=(i的全部员工的dp[u][0相加,也就是其子员工都不能不来的最大快乐值。
从大boss开始dp,最终结果就是max(dp[root][0],dp[root][1])

代码:

#include 
#include
#include
using namespace std;const int maxn = 6060;int n, happy[maxn], dp[maxn][2], p[maxn];vector
sons[maxn];bool vis[maxn];void dfs(int u) { if (vis[u]) return; vis[u] = true; dp[u][1] = happy[u], dp[u][0] = 0; for (int i = 0; i < sons[u].size(); i ++) { int v = sons[u][i]; if (v == p[u]) continue; dfs(v); dp[u][1] += dp[v][0]; dp[u][0] += max(dp[v][1], dp[v][0]); }}void test() { for (int i = 1; i <= n; i ++) { cout << "dp[" << i << "] = " << dp[i][1] << " , " << dp[i][0] << endl; }}int main() { while (cin >> n) { if (!n) break; fill(p+1, p+1+n, -1); fill(vis+1, vis+1+n, false); for (int i = 1; i <= n; i ++) cin >> happy[i]; int a, b; for (int i = 1; i < n; i ++) { cin >> a >> b; p[a] = b; sons[b].push_back(a); } int root = 1; while (p[root] != -1) root = p[root]; dfs(root); cout << max(dp[root][1] , dp[root][0]) << endl; // test(); } return 0;}

参考链接:

转载于:https://www.cnblogs.com/zifeiy/p/10711903.html

你可能感兴趣的文章