hdu 1011 树形dp+背包

题意:有n个房间结构可看成一棵树,有m个士兵,从1号房间开始让士兵向相邻的房间出发,每个房间有一定的敌人,每个士兵可以对抗20个敌人,士兵在某个房间对抗敌人使无法走开,同时有一个价值,问你花费这m个士兵可以得到的最大价值是多少

链接:点我

分析:树形dp,对于点u,dp[u][j]表示以u为根的树消耗j个士兵得到的最大值,dp[i][j]=max(dp[i][j],dp[i][j-k]+dp[son][k]+val[u])

注意是无向图,vis位置不能随便放,且注意dp不能直接+val,因为这样根节点就加不到val了

虽然方程很快就想出来了,真写起来wa点还是很多的

第二次做

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<queue>
 7 #include<map>
 8 using namespace std;
 9 #define MOD 1000000007
10 const int INF=0x3f3f3f3f;
11 const double eps=1e-5;
12 typedef long long ll;
13 #define cl(a) memset(a,0,sizeof(a))
14 #define ts printf("*****\n");
15 const int MAXN=601;
16 int n,m,tt;
17 int aa[MAXN];
18 int tot,head[MAXN],dp[MAXN][MAXN],in[MAXN];
19 int bug[MAXN],val[MAXN],vis[MAXN];
20 struct Edge
21 {
22     int to,next;
23 }edge[MAXN<<2];
24 void addedge(int u,int v)
25 {
26     edge[tot].to=v;
27     edge[tot].next=head[u];
28     head[u]=tot++;
29 }
30 void dfs(int u)
31 {
32     vis[u]=1;
33     int num=(bug[u]+19)/20;
34     for(int i=num;i<=m;i++) dp[u][i]=val[u];
35     for(int i=head[u];i!=-1;i=edge[i].next)
36     {
37         int v=edge[i].to;
38         if(vis[v])  continue;
39         dfs(v);
40         for(int j=m;j>=num;j--)
41         {
42             for(int k=1;j-k>=num;k++)    //派k人攻打其他地方
43             {
44                 dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]);
45             }
46         }
47     }
48 }
49 void init()
50 {
51     tot=0;
52     memset(head,-1,sizeof(head));
53     cl(dp);
54     cl(vis);
55 }
56 int main()
57 {
58     int i,j,k;
59     #ifndef ONLINE_JUDGE
60     freopen("1.in","r",stdin);
61     #endif
62     while(scanf("%d%d",&n,&m)!=EOF)
63     {
64         if(n==-1&&m==-1)  break;
65         init();
66         for(i=1;i<=n;i++)
67         {
68             scanf("%d%d",&bug[i],&val[i]);
69         }
70         int u,v;
71         for(i=1;i<=n-1;i++)
72         {
73             scanf("%d%d",&u,&v);
74             addedge(u,v);
75             addedge(v,u);
76         }
77         if(m==0)
78         {
79             printf("0\n");
80             continue;
81         }
82         dfs(1);
83         printf("%d\n",dp[1][m]);
84     }
85 }

 

posted @ 2015-05-11 00:21  miao_a_miao  阅读(187)  评论(0编辑  收藏  举报