标签:
Description
Input
Output
Sample Input
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0
Sample Output
5
题目大意:给你一 棵关系树,让你从中选择若干个人,这些人之间不能有直接的上下级关系,要求最后的到的权值最大
解析见代码:
/* hdu1520 简单树状DP 解题包括以下几步 1.关系树的建立(用一个结构体来储存某个节点所包含的信息。) 2.确定状态转移方程 f[i][0]表示不选该节点,f[i][1]表示选择该节点,子树能够得到的最大权值 j为i的子节点,f[i][1]=1+f[j][0],f[i][0]=max(f[j][0],f[j][1]) 最后答案就是max(f[root][1],f[root][0]) 3.编程实现,记忆化搜索,相当于树的后序遍历(从子到根) */ #include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> using namespace std; const int maxn = 6000 + 10; int fa[maxn]; int f[maxn][2]; int indegree[maxn]; bool vis[maxn]; int v[maxn]; int n; void dfs(int x) { vis[x]=true; for(int i=1;i<=n;i++) { if(!vis[i]&&fa[i]==x) { dfs(i); f[x][0]+=max(f[i][1],f[i][0]); f[x][1]+=f[i][0]; } } } int main() { int a,b; while(~scanf("%d",&n)) { for(int i=1;i<=n;i++) scanf("%d",&v[i]); memset(indegree,0,sizeof(indegree)); memset(outdegree,0,sizeof(outdegree)); while(scanf("%d%d",&a,&b)) { if(a==0&&b==0) break; fa[a]=b; indegree[a]++; } memset(f,0,sizeof(f)); memset(vis,false,sizeof(vis)); for(int i=1;i<=n;i++)//边界初始化 { f[i][1]=v[i]; } // cout<<indegree[5]<<endl; for(int i=1;i<=n;i++) { if(indegree[i]==0) { dfs(i); printf("%d\n",max(f[i][0],f[i][1])); break; } } } return 0; }
标签:
原文地址:http://www.cnblogs.com/xuejianye/p/5657164.html