/*
http://acm.hdu.edu.cn/showproblem.php?pid=1011 Starship Troopers
01树形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 2
0 1 0 1 0 5 0 1 0 2
1 2 1 3 2 4 2 5
6 3
0 0 20 10 20 10 20 10 20 0 20 5
1 2 1 3 1 4 1 5 2 6
1 0
10 10
5 10
50 10 40 10 40 20 65 30 70 30
1 2 1 3 2 4 2 5
7 10
50 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 1
20 7
5 0
50 10 40 10 40 20 65 30 70 30 1 2
1 3 2 4 2 5
4 1
0 10 0 10 0 10 0 10
1 2 2 3 1 4
-1 -1
result
9
30
0
50
90
7
0
30
*/
HDU 1011 Starship Troopers - 01树形dp 有坑啊!!
最新推荐文章于 2013-10-12 09:57:48 发布