您的位置:首页 > 其它

hdu 1011(树形dp)

2014-05-26 18:06 232 查看
题目链接: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
 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: