hdu(1520) Anniversary party(树形dp)
2013-07-05 21:30
435 查看
树形dp入门题,dp[i][1] 表示选择i结点的最大值,dp[i][0]表示不选i结点的最大值。
则方程为
dp[i][1] += dp[i的所有孩子][0] (依题意,i选了,i的孩子就一定不能选)
dp[i][0] += max(dp[i的所有孩子][0],dp[i的所有孩子][1]) (i不选,则他的孩子可以选,也可以不选,我们选择二者的最大值)
存图的时候我用了一个vector的二维数组存下每个结点所有的孩子数。
则方程为
dp[i][1] += dp[i的所有孩子][0] (依题意,i选了,i的孩子就一定不能选)
dp[i][0] += max(dp[i的所有孩子][0],dp[i的所有孩子][1]) (i不选,则他的孩子可以选,也可以不选,我们选择二者的最大值)
存图的时候我用了一个vector的二维数组存下每个结点所有的孩子数。
#include<cstring> #include<cstdio> #include<vector> #include<algorithm> using namespace std; int rank[6005]; vector<int> son[6005]; bool isroot[6005]; int dp[6005][2]; int n; void treedp(int k) { if(son[k].size()==0) { dp[k][1]=rank[k]; dp[k][0]=0; return; } dp[k][0]=0; dp[k][1]=rank[k]; for(int i=0;i<son[k].size();i++) { treedp(son[k][i]); dp[k][1]+=dp[son[k][i]][0]; dp[k][0]+=max(dp[son[k][i]][1],dp[son[k][i]][0]); } } int main() { int l,k; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++) { scanf("%d",&rank[i]); son[i].clear(); } memset(isroot,0,sizeof(isroot)); while(scanf("%d%d",&l,&k)&&(l||k)) { son[k].push_back(l); isroot[l]=1; } int i; for(i=1;i<=n;i++) { if(!isroot[i]) { treedp(i); break; } } printf("%d\n",max(dp[i][1],dp[i][0])); } return 0; }
相关文章推荐
- HDU1520 Anniversary party 树形dp
- hdu1520 Anniversary party 树形dp
- [HDU] 1520 Anniversary party 入门树形DP
- hdu 1520 Anniversary party(入门树形DP)
- hdu 1520 Anniversary party(树形DP)
- hdu1520 Anniversary party(树形dp)
- HDU-1520 Anniversary party(树形DP)
- HDU 1520 Anniversary party 树形DP
- HDU 1520 Anniversary party(树形DP-最大独立集)
- HDU-1520-Anniversary party(树形DP入门)
- POJ 2342 & HDU 1520 Anniversary party (树形DP)
- hdu 1520 Anniversary party(树形DP)
- hdu 1520 Anniversary party 树形dp水题
- hdu 1520 Anniversary party(树形DP入门)
- 【树形DP】hdu 1520 Anniversary party
- hdu 1520 Anniversary party 树形dp水题
- HDU 1520 Anniversary party(树形DP入门)
- HDU 1520 Anniversary party(树形DP 数组和结构体链表两种实现方式)
- Anniversary party HDU - 1520(树形dp)
- HDU 1520 Anniversary party (树形DP)