没有上司的舞会——树形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
标签:舞会,子树,int,sum,树形,为根,dp 来源: https://www.cnblogs.com/wellerency/p/16102618.html