[关闭]
@iamtts 2017-03-31T15:30:20.000000Z 字数 911 阅读 717

寒假第七次训练-动态规划

F - 树形DP

题目大意:举办一个party,邀请若干人参加,每个人都不愿意和直接上司一同出席(太过扫兴),每个人自身带有活跃值,设计一个邀请方案使得party的总活跃值最大,不存在环。

解题思路:用树形dp解决。若a为b的直接上司,那么dp[a][0]表示a不出席,dp[a][1]表示a出席

a不来时: dp[a][0]+=max(dp[b][1],dp[b][0])
a来时 : dp[a][1]=dp[b][0]

AC代码:

  1. #include<iostream>
  2. #include<cmath>
  3. #include<algorithm>
  4. #include<vector>
  5. #include<cstdio>
  6. #include<cstdlib>
  7. #include<cstring>
  8. #include<string>
  9. using namespace std;
  10. #define maxn 6005
  11. int n;
  12. int dp[maxn][2],father[maxn];
  13. void tree_dp(int node)
  14. {
  15. int i;
  16. for(i=1; i<=n; i++)
  17. {
  18. if(father[i] == node)
  19. {
  20. tree_dp(i);
  21. dp[node][1] += dp[i][0];
  22. dp[node][0] +=max(dp[i][1],dp[i][0]);
  23. }
  24. }
  25. }
  26. int main()
  27. {
  28. int i;
  29. int f,c,root;
  30. while(scanf("%d",&n)!=EOF)
  31. {
  32. memset(dp,0,sizeof(dp));
  33. memset(father,0,sizeof(father));
  34. for(i=1; i<=n; i++)
  35. {
  36. scanf("%d",&dp[i][1]);
  37. }
  38. root = 0;
  39. bool beg = 1;
  40. while (scanf("%d %d",&c,&f),c||f)
  41. {
  42. father[c] = f;
  43. if( root == c || beg )
  44. {
  45. root = f;
  46. }
  47. }
  48. while(father[root])
  49. root=father[root];
  50. tree_dp(root);
  51. int imax=max(dp[root][0],dp[root][1]);
  52. printf("%d\n",imax);
  53. }
  54. return 0;
  55. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注