标签:imu struct eve 分组背包 nes problem new leading 子节点
5 10 50 10 40 10 40 20 65 30 70 30 1 2 1 3 2 4 2 5 1 1 20 7 -1 -1
50 7
这个题目是在树形DP的基础上在每个节点的一个分组背包问题
首先根据题目条件建立一颗树,然后DFS整棵树,每个节点的dp[i][j]
表示以这个i节点为根,放j个士兵最多能得到brains的个数!
注意:只有根节点的bug全被消灭,才能访问子节点
#include <iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<vector> using namespace std; int dp[105][105],bug[105],brain[105]; //dp[i][j]表示第i个节点放置j个士兵 bool vis[105]; int n,m; vector<int> mp[105]; void dfs(int k) { vis[k]=1; for(int i=bug[k];i<=m;i++) dp[k][i]=brain[k]; for(int i=0;i<mp[k].size();i++) { if (vis[mp[k][i]]) continue; dfs(mp[k][i]); for(int j=m;j>=bug[k];j--)//一定要倒序,类似01背包 for(int q=1;q+j<=m;q++) //只要父节点和子节点的士兵总和不超过m的情况都要看看这种可能 dp[k][j+q]=max(dp[k][j+q],dp[k][j]+dp[mp[k][i]][q]); /* 之前写成 for(int j=m;j>=bug[k];j--) for(int q=1;q<=j-bug[k];q++) dp[u][j]=max(dp[u][j],dp[u][j-q]+dp[v][q]); 这是错误的,一直wa还找不到错误在哪,网上的这个代码放到hdu里也是错的 */ } return; } int main() { while(~scanf("%d%d",&n,&m)) { if (n==-1 && m==-1) break; for(int i=1;i<=n;i++) { scanf("%d%d",&bug[i],&brain[i]); if (bug[i]%20!=0) bug[i]=bug[i]/20+1;//处理成要放的士兵个数 else bug[i]=bug[i]/20; mp[i].clear(); } for(int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); mp[x].push_back(y); mp[y].push_back(x); } if (m==0) {printf("0\n"); continue;} memset(vis,0,sizeof(vis)); memset(dp,0,sizeof(dp)); dfs(1); printf("%d\n",dp[1][m]); } return 0; }
HDU 1011 Starship Troopers(树形DP)
标签:imu struct eve 分组背包 nes problem new leading 子节点
原文地址:http://www.cnblogs.com/stepping/p/6391503.html