标签:pac tar ios dia eof inf each void ber
http://acm.timus.ru/problem.aspx?space=1&num=1039
<L> <K>
0 0
input | output |
---|---|
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0 |
5 |
树上的树dp例题,f[i][0]表示以i为根不包含i可获得的最大价值,f[i][1]表示以i为根包含i在内可获得的最大价值。有f[i][0]+=MAX{f[son[i]][0],f[son[i]][1] } ,f[i][1]+=f[son[i]][0];
因为一旦包含i了显然不能包含i的儿子,所以不能加上f[son[i]][1],反之取二者中较大的就好了。
因为如何保存他们之间的关系想了半天,想用vector来着,看书上写的很简便,利用数组做邻接表处理。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 #define LL long long 7 #define inf 0x3f3f3f3f 8 int c[6005],fa[6005],son[6005],bro[6005]; 9 int dp[6005][2]; 10 void solve(int id) 11 { 12 dp[id][0]=0; 13 dp[id][1]=c[id]; 14 for(int i=son[id];i!=-1;i=bro[i]) 15 { 16 solve(i); 17 dp[id][0]+=max(dp[i][0],dp[i][1]); 18 dp[id][1]+=dp[i][0]; 19 } 20 } 21 int main() 22 { 23 int N,i,j,k; 24 while(cin>>N){ 25 int a,b,root; 26 memset(fa,-1,sizeof(fa)); 27 memset(son,-1,sizeof(son)); 28 memset(bro,-1,sizeof(bro)); 29 for(i=1;i<=N;++i) scanf("%d",c+i); 30 while(scanf("%d%d",&a,&b)&&(a||b)){ 31 fa[a]=b; 32 bro[a]=son[b]; 33 son[b]=a; 34 } 35 for(i=1;i<=N;++i){ 36 dp[i][0]=0,dp[i][1]=c[i]; 37 if(fa[i]==-1) root=i; 38 } 39 solve(root); 40 printf("%d\n",max(dp[root][0],dp[root][1])); 41 } 42 return 0; 43 }
标签:pac tar ios dia eof inf each void ber
原文地址:http://www.cnblogs.com/zzqc/p/7470406.html