HDU 1520 Anniversary party【树形DP】
L K
It means that the K-th employee is an immediate supervisor of the L-th employee. Input is ended with the line
0 0
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0
5
思路 |
和经典的树形DP简介上司差不多,我的第一道树形DP,看了一个大牛的博客才有点印象,树形DP大概怎么写。思路是:每个人的状态只有两种,取或者不取。因此从叶子节点往根遍历,对于每个节点有状态方程如下:(1代表取,0代表不取) dp[i][1]+=dp[i.son][0]; dp[i][0]+=max(dp[i.son][1], dp[i.son][0]); |
源码 |
#include<stdio.h> #include<string.h> #include<iostream> #include<vector> using namespace std; int root, lovely[6005]; vector<int>V[6005]; int dp[6005][3]; void dfs(int rr) { int len=V[rr].size(), i, j; if(len==0) { dp[rr][0]=0; dp[rr][1]=lovely[rr]; return ; } for(i=0; i<len; i++) { dfs(V[rr][i]); dp[rr][0]=0; dp[rr][1]=lovely[rr]; for(j=0; j<len; j++) { dp[rr][0]+=max(dp[V[rr][j]][1], dp[V[rr][j]][0]); dp[rr][1]+=dp[V[rr][j]][0]; } } } int main() { int n, i, j, son[6005], l, k; while(scanf("%d", &n)!=EOF) { for(i=0; i<=6000; i++) V[i].clear(); memset(son, 0, sizeof(son)); for(i=1; i<=n; i++) scanf("%d", &lovely[i]); for(i=1; i<=n; i++) { scanf("%d%d", &l, &k); if(l==0&&k==0) break; son[l]=1; V[k].push_back(l); } for(i=1; i<=n; i++) if(!son[i]) { root=i; break; } memset(dp, 0, sizeof(dp)); dfs(root); printf("%d\n", max(dp[root][1], dp[root][0])); } } |