树形DP
题意:给出每个房间拥有的BUG数和能得到的能量数,然后给出每个房间的联通图,要到下一个房间必须攻破上一个房间,每个士兵最多消灭20个BUG,就算不足20个BUG也要安排一个士兵
思路:先建立树,然后进行树形DP
http://acm.hdu.edu.cn/showproblem.php?pid=1011
Time
Limit: 10000/5000 MS (Java/Others) Memory Limit:
65536/32768 K (Java/Others)
Total Submission(s):
9538 Accepted Submission(s):
2640
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 |
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int
head[ 200 ], len ,dp[ 200 ][ 200 ];; int
n,m,a[ 200 ],b[ 200 ],mark[ 200 ]; struct node { int
now; int
next ; }tree[ 200 ]; void add( int
x, int
y) { tree[ len ].now =
y; tree[ len ]. next
= head[x]; head[x] =
len + + ; } void dfs( int
root) { int
i,vel,j,k,son; mark[root] = 1 ; vel = (a[root] + 19 ) / 20 ; / / 不足 20 的部分也要安排一个 for (i = vel;i< = m;i + + ) dp[root][i] = b[root]; / / 小于vel的无法获得经验 for (i = head[root];i! = - 1 ;i = tree[i]. next ) { son = tree[i].now; if (mark[son] = = 0 ) { dfs(son); for (j = m;j> = vel;j - - ) for (k = 1 ;k + j< = m;k + + ) / / 到达r的有j + k人,如果留在r有j人,则到达后继节点有k人 dp[root][j + k] = max (dp[root][j + k],dp[root][j] + dp[son][k]); } } } int
main() { int
i,x,y; while (~scanf( "%d%d" ,&n,&m)&&n! = - 1 &&m! = - 1 ) { len = 0 ; memset(head, - 1 ,sizeof(head)); memset(dp, 0 ,sizeof(dp)); memset(mark, 0 ,sizeof(mark)); for (i = 1 ;i< = n;i + + ) cin>>a[i]>>b[i]; for (i = 1 ;i<n;i + + ) { cin>>x>>y; add(x,y); add(y,x); } dfs( 1 ); if (m = = 0 ) printf( "0\n" ); else printf( "%d\n" ,dp[ 1 ][m]); } return
0 ; } |
HDU-1011 Starship Troopers,布布扣,bubuko.com
原文:http://www.cnblogs.com/cancangood/p/3626021.html