hdu 1011(树形DP)

来源:互联网 发布:如何攻击80端口 编辑:程序博客网 时间:2024/04/30 06:13

hdu 1011

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1011

题目大意:一棵树,有n个节点,根节点编号为1,即入口,每个节点有一些Bugs及Brains,现在有m个士兵,一个士兵能打20个Bugs,让你用这些士兵去攻打这个Cave,最多能获得多少Brains。

思路:好吧,我承认我做了很久。状态方程还是比较简单的,d[ u ][ i ] = max(d[ u ][ i ] , d[ v ][ j ]+d[ u ][ i-j ]) , j<=i ; 细节啊,处理了半天,跑出样例了,一交,还是WA,看了半天没看出来。后来一看DISCUSS,原来有一个trick,发现如果一个洞穴的Bugs = 0,那么也需要至少派一个士兵走过,但可以不停留。有一组数据:

5 20 1 0 1 0 5 0 1 0 2 1 2 1 3 2 4 2 5
答案是9!不相信自己画画就知道了。 = = 

知道哪里有问题,想了想还不知道怎么改。。 再次去网上看了一下,加了两句话:

d[u][1]=max(d[u][1],d[u][0]);
d[u][0]=-INF;

唉,还是不行啊,树形DP继续练吧!

代码如下:

#include<cstdio>#include<cstring>#include<vector>#include<algorithm>using namespace std;const int MAXN = 111 ;const int INF = 0X0FFFFFFF ;struct Cave{    int bugs,bra;} cave[MAXN];int vis[MAXN];int n,m;vector <int> G[MAXN];int d[MAXN][MAXN];void dfs(int u){    vis[u]=1;    for(int i=0;i<=m;i++)        d[u][i]=-INF;    d[u][cave[u].bugs] = cave[u].bra;    for(int i=0;i<G[u].size();i++)    {        int v = G[u][i];        if(!vis[v])        {            dfs(v);            //printf("u = %d,v = %d\n" ,u,v);            for(int j = m;j>=cave[u].bugs;j--)                for(int k = 0;k<=j;k++)                {                    d[u][j] = max(d[u][j],d[v][k]+d[u][j-k]);                    //printf("d[%d][%d] = %d\n",u,j,d[u][j]);                }        }    }    d[u][1]=max(d[u][1],d[u][0]);    d[u][0]=-INF;}int main(){    while(~scanf("%d%d",&n,&m))    {        if(n==-1&&m==-1) break;        for(int i=1;i<=n;i++)        {            scanf("%d%d",&cave[i].bugs,&cave[i].bra);            cave[i].bugs = (cave[i].bugs+19)/20;        }        int a,b;        for(int i=1;i<=n;i++)            G[i].clear();        for(int i=1;i<n;i++)        {            scanf("%d%d",&a,&b);            G[a].push_back(b);            G[b].push_back(a);        }        memset(vis,0,sizeof(vis));        dfs(1);        int ans=0;        for(int i=1;i<=m;i++)            ans=max(ans,d[1][i]);        printf("%d\n",ans);    }    return 0;}


原创粉丝点击