hdu 1011(树形dp)

来源:互联网 发布:linux多线程编程 书籍 编辑:程序博客网 时间:2024/05/17 06:09

题目链接: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

 

 

0 0
原创粉丝点击