标签:des style blog http color os io for
很好的树形DP入门题,看着和选课那道题如出一辙。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 5 using namespace std; 6 7 int dp[208][208],map[208][208]; 8 int num[208]; 9 bool visited[208]; 10 int N,M; 11 12 inline int max(int a,int b) 13 { 14 if(a>b) return a; 15 return b; 16 } 17 18 int TreeDP(int father) 19 { 20 visited[father]=true; //第father号城市已访问过 21 for(int i=1;i<=num[father];i++) //遍历以father为根节点的子节点 22 { 23 int son=map[father][i]; 24 if(!visited[son]) TreeDP(son);//递归遍历直至为叶子节点,然后返回 25 for(int j=M;j>=2;j--)//j>=2的原因是输入a,b是j=1已经考虑进去了 26 for(int k=1;k<j;k++)//拆分 27 { 28 if(dp[father][j-k]!=-1&&dp[son][k]!=-1)//是否可以进行拆分 29 dp[father][j]=max(dp[father][j],dp[father][j-k]+dp[son][k]);//由状态转移方程式得 30 } 31 } 32 } 33 int main() 34 { 35 //dp[i][j]代表的是攻克包括第i号城市在内的共j座城市所获得的财富值 36 int a,b; 37 while(scanf("%d %d",&N,&M),N||M)//M原本代表ACBoy要攻打城市的个数,但为了方便森林变成数时更好统计就把M++,这样0号城市也纳入其中 38 { 39 memset(dp,-1,sizeof(dp)); 40 memset(num,0,sizeof(num));//num[father]表示以father为根节点的子节点个数有多少个 41 dp[0][1]=0; 42 for(int i=1;i<=N;i++) 43 { 44 scanf("%d %d",&a,&b); 45 dp[i][1]=b; //攻打第i号城市的财富值 46 map[a][++num[a]]=i; //构成一棵树,第0号城市为根节点 47 } 48 M++; 49 for(int i=0;i<=N;i++)//初始化 50 { 51 dp[i][0]=0; 52 visited[i]=false; 53 } 54 TreeDP(0); 55 printf("%d\n",dp[0][M]); 56 } 57 58 return 0; 59 }
dp[i][j]代表的是包括第i座城市在内的共j座城市所获得的最大财富值
树形DP-HDU1561 The more, The Better,布布扣,bubuko.com
树形DP-HDU1561 The more, The Better
标签:des style blog http color os io for
原文地址:http://www.cnblogs.com/Chinahenu/p/3914245.html