hdu 1011(树形dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1011

思路:dp[i][j]表示以i为根的子树派遣j个士兵占领的最大价值。

 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<algorithm>

 5 #include<vector>

 6 using namespace std;

 7 #define MAXN 111

 8 

 9 

10 int dp[MAXN][MAXN];

11 int num[MAXN],val[MAXN];

12 int n,m;

13 bool mark[MAXN];

14 vector<vector<int> >G;

15 

16 void dfs(int u)

17 {

18     mark[u]=true;

19     for(int i=num[u];i<=m;i++){

20         dp[u][i]=val[u];

21     }

22     for(int i=0;i<G[u].size();i++){

23         int v=G[u][i];

24         if(mark[v])continue;

25         dfs(v);

26         for(int i=m;i>=num[u];i--){

27             for(int j=1;j+i<=m;j++){

28                 if(dp[v][j]){

29                     dp[u][i+j]=max(dp[u][i+j],dp[u][i]+dp[v][j]);

30                 }

31             }

32         }

33     }

34 }

35 

36 

37 int main()

38 {

39     int u,v,ans;

40     while(~scanf("%d%d",&n,&m)){

41         if(n==-1&&m==-1)break;

42         G.clear();

43         G.resize(n+2);

44         for(int i=1;i<=n;i++){

45             scanf("%d%d",&num[i],&val[i]);

46             num[i]=(num[i]+19)/20;

47         }

48         for(int i=1;i<n;i++){

49             scanf("%d%d",&u,&v);

50             G[u].push_back(v);

51             G[v].push_back(u);

52         }

53         memset(dp,0,sizeof(dp));

54         memset(mark,false,sizeof(mark));

55         dfs(1);

56         ans=0;

57         for(int i=1;i<=m;i++){

58             ans=max(ans,dp[1][i]);

59         }

60         printf("%d\n",ans);

61     }

62     return 0;

63 }

64 

65 

66 

67         
View Code

 

 

你可能感兴趣的:(HDU)