hdu 1011 Starship Troopers

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

题目大意:

        外星球上一共有N个山洞,以N-1条通道相连,就是一个树的结构,山洞里有一些虫子,每个山洞里有敌方首领的可能性,部队要去消灭他们,并要制定一套最大可能性制服首领的方案,其实就是找一条最大可能性和的路径。每个士兵能对付20只虫子,现在有m个士兵,从1号山洞出发,求最大可能性的和。

 

解题小结:

      标准树形动态规划,用opt[i][j]表示在以i号洞口为根的子树里共派出j个人所能获得的最大值。我的程序要特判一下m=0的情况。

      方程:opt[i][j]=Max(opt[i][j],opt[i][j-k]+opt[son[i]][k]),k枚举派去孩子节点的士兵数目。

 

代码:

#include <iostream>
using namespace std;

int n,m,Need,Num[101],opt[101][101],num[101],v[101],Visit[101];
bool f[101][101];

int Max(int x,int y)
{
    if (x>y)
        return x;
    return y;
}

void Dfs(int t)
{
    int Need,i,j,k;
    Visit[t]=1;
    Need=(Num[t]+19)/20;
    for (i=Need;i<=m;i++)
        opt[t][i]=v[t];
    for (i=1;i<=n;i++)
        if (f[t][i]&&!Visit[i])
        {
            Dfs(i);
            for (j=m;j>=Need;j--)
                for (k=1;k<=j-Need;k++)
                    opt[t][j]=Max(opt[t][j],opt[t][j-k]+opt[i][k]);
        }
    /*if (opt[t][0]>0)
    {
        opt[t][1]=Max(opt[t][1],opt[t][0]);
        opt[t][0]=0;
    }*/
}

void init()
{
    int i,x,y;
    memset(f,0,sizeof(f));
    memset(Visit,0,sizeof(Visit));
    memset(opt,0,sizeof(opt));
    for (i=1;i<=n;i++)
        cin >> Num[i] >> v[i];
    for (i=1;i<=n-1;i++)
    {    
        cin >> x >> y;
        f[x][y]=1;
        f[y][x]=1;
    }
}


int main()
{
    while (cin >> n >> m&&n!=-1)
    {
        init();
        if(m==0) {cout << "0\n";continue;}
        Dfs(1);
        cout << opt[1][m] << endl;
    }
    return 0;
}


])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值