HDU 1011 Starship Troopers - 01树形dp 有坑啊!!

来源:互联网 发布:iptv与网络电视的区别 编辑:程序博客网 时间:2024/06/05 23:06
/*http://acm.hdu.edu.cn/showproblem.php?pid=1011 Starship Troopers01树形dp题意:多个舰队,攻打bug的洞穴,每一个洞穴里面有很多bug和一些brain,我们需要派一个舰队去获得更多的brain这个过程我们遵循:洞穴为一个树形结构(没有环),洞穴的入口为1(root节点),如果洞穴i在洞穴j的前面,则必须先进攻洞穴i方可进攻洞穴j,同时如果一个洞穴有0个bug还必须要舰队进过才可获取brain,其中舰队不走回头路一个舰队可以杀死20个bug显然思路是 01树形dp,抽象后物品(c,v)为洞穴(bus/20,brain),消耗上限为舰队个数,坑啊!!如果存在分叉后消耗为两个0,则消耗必须为2才能全部获取,否则最多获取一个物品,我们在循环的时候控制一下就好了*/#pragma comment(linker, "/stack:64000000")#define _CRT_SECURE_NO_DEPRECATE#include <queue>#include <cmath>#include <cstdio>#include <string>#include <cstring>#include <iostream>using namespace std;#define CLR(c,v) memset(c,v,sizeof(c))template <typename _T>_T Max(_T a , _T b){return (a>b)?(a):(b);}template <typename _T>_T Max(_T a , _T b, _T c){return (a>Max(b,c))?(a):(Max(b,c));}template <typename _T>_T Min(_T a , _T b){return (a<b)?(a):(b);}template <typename _T>_T Min(_T a , _T b, _T c){return (a<Min(b,c))?(a):(Min(b,c));}const int inf    = -(1<<30);const int INF    =  (1<<30);const int M      =  1e2 +10;const double eps =  1e-8;vector <int > p[M];int v[M];int c[M];int dp[M][M];int n_cavern, max_cost;void dfs(int cur){int len  = p[cur].size();for (int i = 0 ; i < len ; i ++){int father = cur; int child = p[cur][i];dfs(child);for (int i = max_cost; i >= c[father]; i--){ //fu ==0 er == 1  fu ==1 for(int j=1; j+i<=max_cost ; j++){ // dp[father][i] + dp[child][j] dp[father][i+j] = Max(dp[father][i+j], dp[father][i] + dp[child][j]);}} // 这个不能保证每一个支路有一个士兵存在,//可能所有点的消费为0 一个士兵就全部占领了,这是不对的。(无法控制消费为0的边界)//int bound1 = c[father]; //for (int all_cost = max_cost; all_cost >= bound1  ; all_cost--){ // 更新父节点(总消费)//int bound2 = all_cost-c[father];//for(int k = c[father] ; k <= bound2 ; k++){ // 遍历父节点(k)与子节点(all-k)不同消费组合的价值//int child_cost = all_cost - k; // //dp[father][all_cost] = Max(dp[father][all_cost] , dp[father][k] + dp[child][child_cost] );//}//}}}int main(){freopen("in.txt","r",stdin);while(cin >> n_cavern >> max_cost , n_cavern!=-1&&max_cost!=-1){CLR(dp,0);for(int i = 1 ; i <= n_cavern ; i ++){cin >> c[i] >> v[i];c[i] = (int)ceil(c[i]/20.0-eps);p[i].clear();for(int j = c[i] ; j <= max_cost ; j++)dp[i][j] = v[i]; }for(int i = 0 ; i < n_cavern-1 ; i ++){int a,b;cin >> a >> b;if(a>b)a^=b^=a^=b;p[a].push_back(b); // a<b 没有环可以不用标记}if(max_cost == 0){cout << 0 << endl;continue;}dfs(1);cout << dp[1][max_cost] << endl;}return 0;}/*5 20 1 0 1 0 5 0 1 0 2 1 2 1 3 2 4 2 5 6 30 0 20 10 20 10 20 10 20 0 20 5 1 2 1 3 1 4 1 5 2 6 1 010 105 1050 10 40 10 40 20 65 30 70 30 1 2 1 3 2 4 2 5 7 1050 10 40 10 40 20 65 30 70 30 35 40 45 20 1 2 1 3 2 4 2 5 7 3 6 3 1 120 75 050 10 40 10 40 20 65 30 70 30 1 2 1 3 2 4 2 5 4 10 10 0 10 0 10 0 10 1 2 2 3 1 4 -1 -1result930050907030*/

原创粉丝点击