树形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