没有上司的舞会——树形dp

P1352 没有上司的舞会 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

一道很好的树形dp入门题。

要明确树形dp主要的实现方式是dfs。

 

状态表示:f [ i , 0 ]表示以i为根的子树,i层不取值时的最大值。

     f [ i , 1 ]表示以i为根的子树,i层取值时的最大值

状态计算:f [ i , 0 ] = sum max ( f [ j  , 1 ] , f [ j , 0 ] )

     f [ i , 1 ] = sum f [ j , 0 ] + a [ i ]

       其中j是i的子节点

 

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N=6e3+100;
 4 int a[N],f[N][3];
 5 bool st[N];
 6 vector<int> son[N];
 7 
 8 void dp(int u)
 9 {
10     f[u][0]=0;
11     f[u][1]=a[u];
12     for(int i=0;i<son[u].size();i++)
13     {
14         int y=son[u][i];
15         dp(y);
16         f[u][0]+=max(f[y][0],f[y][1]);
17         f[u][1]+=f[y][0];
18     }
19 }
20 
21 int main()
22 {
23     int n;scanf("%d",&n);
24     for(int i=1;i<=n;i++)scanf("%d",&a[i]);
25     
26     for(int i=1;i<=n-1;i++)
27     {
28         int x,y;scanf("%d%d",&x,&y);
29         st[x]=1;
30         son[y].push_back(x);
31     }
32     
33     int root;
34     for(int i=1;i<=n;i++)
35     {
36         if(!st[i])
37         {
38             root=i;
39             break;
40         }
41     }
42     
43     //cout<<"***"<<root<<endl;
44     dp(root);
45     printf("%d\n",max(f[root][1],f[root][0]));
46     
47     return 0;
48 }
View Code

 

posted @ 2022-04-05 15:49  wellerency  阅读(25)  评论(0编辑  收藏  举报