dp--树形dp P1352 没有上司的舞会

题目描述

某大学有N个职员,编号为1~N。他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司。现在有个周年庆宴会,宴会每邀请来一个职员都会增加一定的快乐指数Ri,但是呢,如果某个职员的直接上司来参加舞会了,那么这个职员就无论如何也不肯来参加舞会了。所以,请你编程计算,邀请哪些职员可以使快乐指数最大,求最大的快乐指数。

输入格式

第一行一个整数N。(1<=N<=6000)

接下来N行,第i+1行表示i号职员的快乐指数Ri。(-128<=Ri<=127)

接下来N-1行,每行输入一对整数L,K。表示K是L的直接上司。

最后一行输入0 0

输出格式

输出最大的快乐指数。

因为除了终极大boss外,每个职工都有一个直接上司,其实题目也告诉了我们,这就是一颗树。

用vector存一个有向图,从大boss开始,每次可以分为两种情况,去和不去

去的时候:他的子节点必然不去;

不去的时候:他的子节点可能去也可能不去,所以我们要取两种情况里大的那一种哇

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <algorithm>
 5 #include <cmath>
 6 using namespace std;
 7 int n;
 8 int r[6005];
 9 int x,y;
10 int l,k;
11 int f[60005][2];
12 vector <int> q[6005];
13 int fa[60005];
14 void dp(int x) {
15     f[x][0]=0;
16     f[x][1]=r[x];
17     for (int i =0; i < q[x].size(); i++) {
18         int use=q[x][i];
19         dp(use);
20         f[x][0]+=max(f[use][0],max(0, f[use][1]));
21         f[x][1]+=max(0, f[use][0]);
22     }
23     return;
24 }
25 int main() {
26     int ans;
27     scanf ("%d",&n);
28     for (int i= 1; i <= n; i++) {
29         scanf ("%d",&r[i]);
30         f[i][1]=r[i];
31         fa[i]=i;
32     }
33     for (int i = 1; i <= n-1; i++) {
34         scanf ("%d%d",&l,&k);
35         q[k].push_back(l);
36         fa[l]=k;
37     }
38     scanf ("%d%d",&x,&y);
39     for (int i =1; i <= n; i++)
40         if(fa[i]==i) {
41             ans=i;
42             break;
43         }
44     dp(ans);    
45     cout<<max(f[ans][0], f[ans][1]);
46     return 0;
47 }

猜你喜欢

转载自www.cnblogs.com/very-beginning/p/12219297.html