标签:dp
题意:有n个洞组成一棵树形结构,你有m个士兵,你从1号房间开始攻打,每个洞有a个bugs和brain的价值。你的一个士兵可以打20个bugs,为了拿到这个洞的价值brain你必须留下k个士兵消灭这个洞的所有bugs(k*20>="bugs"的数量,且留下的士兵不可以再去攻打其他的洞,且必须攻打了前面的洞才可以攻打后面的洞)。问你花费这m个士兵可以得到的最大价值是多少。
思路:树形dp dp[i][j]表示第i个节点安排j个士兵所能取得的最大价值,状态转移方程:
dp[dad][j+k] = max(dp[dad][j+k], dp[dad][j] + dp[son][k]); 其中m = i + j;
ps:提议并未给出明确的谁父谁子,所以建边时 要建双向边。
#include <algorithm> #include <iostream> #include <sstream> #include <cstdlib> #include <cstring> #include <iomanip> #include <cstdio> #include <string> #include <bitset> #include <vector> #include <queue> #include <stack> #include <cmath> #include <list> #include <map> #include <set> #define sss(a,b,c) scanf("%d%d%d",&a,&b,&c) #define mem1(a) memset(a,-1,sizeof(a)) #define mem(a) memset(a,0,sizeof(a)) #define ss(a,b) scanf("%d%d",&a,&b) #define s(a) scanf("%d",&a) #define INF 0x3f3f3f3f #define w(a) while(a) #define PI acos(-1.0) #define LL long long #define eps 10E-9 #define N 100010<<1 #define mod 1000000000+7 using namespace std; void mys(int& res) { int flag=0; char ch; while(!(((ch=getchar())>='0'&&ch<='9')||ch=='-')) if(ch==EOF) res=INF; if(ch=='-') flag=1; else if(ch>='0'&&ch<='9') res=ch-'0'; while((ch=getchar())>='0'&&ch<='9') res=res*10+ch-'0'; res=flag?-res:res; } void myp(int a) { if(a>9) myp(a/10); putchar(a%10+'0'); } /*************************THE END OF TEMPLATE************************/ struct node { int bugs; int brains; int pos; int son[101]; }info[110]; int dp[110][110]; bool vis[110]; int n, m; void tree_dp(int root){ vis[root] = true; int cost = (info[root].bugs + 19)/20; for(int i = cost; i<=m; i++) dp[root][i] = info[root].brains; for(int i = 0; i<info[root].pos; i++){ int next = info[root].son[i]; if(!vis[next]){ tree_dp(next); for(int j = m; j>=cost; j--){ for(int k = 1; j+k<=m; k++){ if(dp[next][k]){//当前情况肯定要在子情况已经明确的情况下决定 dp[root][j + k] = max(dp[root][j+k], dp[root][j] + dp[next][k]); } } } } } } int main(){ w(~ss(n, m)){ if(n == -1 && m == -1) break; mem(info); mem(dp); mem(vis); for(int i=1; i<=n; i++) ss(info[i].bugs, info[i].brains); int x, y; for(int i = 1; i < n; i++){ ss(x, y); info[x].son[info[x].pos++] = y; info[y].son[info[y].pos++] = x; } if(!m) printf("0\n"); else{ tree_dp(1); printf("%d\n", dp[1][m]); } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:dp
原文地址:http://blog.csdn.net/bigsungod/article/details/47082103