hdoj1010Starship Troopers (树dp,依赖背包)

简介:

称号:hdoj1010Starship Troopers 


题意:有一个军队n个人要占据m个城市,每一个城市有cap的驻扎兵力和val的珠宝,并且这m个城市的占率先后具有依赖关系,军队的每一个人能够打败20个城市的防守者,并且占据城市后能够得到城市的珠宝。问最多能够得到多少珠宝?


分类:树形dp入门题。依赖背包


分析:是hdoj1561题目的复杂版。相同我们要构建一颗dp树,从叶子到根往上dp。


定义状态:dp【i】【j】 以节点 i  为根节点的子树。花费 j 的兵力能够得到的最大珠宝数。

状态转移方程:dp【father】【j】 = Max(dp【father】【j】,dp【father】【k】+dp【child】【j-k】)

注意:1:在一个节点即使仅仅有没有兵力,也至少花费1的兵力攻占。

    2:注意初始化


代码:

#include <iostream>
#include <vector>
#include <cstring>
#include <cstdio>
#include <string>
#include <algorithm>
#include <vector>
#define Del(a,b) memset(a,b,sizeof(a))
const int N = 150;
using namespace std;
int n,m;
int dp[N][N],vis[N];  //dp[i][j]表示在节点i,从以i为根节点的子树下选择j个城市的最大价值
int cap[N],val[N];
vector<int> v[N];

void creat(int o)
{
    vis[o]=1;
    int tmp=(cap[o]+19)/20;
    if(tmp>m)
        return ;
    for(int i=tmp; i<=m; i++)
        dp[o][i]=val[o];
    for(int i=0; i<v[o].size(); i++)
    {
        int t=v[o][i];
        if(vis[t]==1)
            continue;
        if(v[t].size()>0)
        {
            creat(t);
            for(int j = m ; j > tmp ; j--)   //j>1表示此节点一定要取 0-1背包
            {
                for(int k=0; k<=j-tmp; k++) //枚举给当前节点的其它子树留多少可选择的城市
                    dp[o][j]=max(dp[o][j],dp[o][j-k]+dp[t][k]);
            }
        }
    }
    if(dp[o][0]>0)//以u为根节点的子树至少要有一个人才干够获得该节点的brain
    {
        dp[o][1]=max(dp[o][1],dp[o][0]);
        dp[o][0]=0;
    }
}

int main()
{
    while(cin >> n >> m )
    {
        if(n==-1 && m==-1)
            break;
        Del(dp,0);
        Del(vis,0);
        for(int i=1; i<=n; i++)
            scanf("%d%d",&cap[i],&val[i]);
        for(int i=1; i<n; i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            v[x].push_back(y);
            v[y].push_back(x);
        }
        creat(1);
        for(int i = 0 ; i <= n ; i ++)
            v[i].clear();
        cout << dp[1][m] << endl;
    }
    return 0;
}


版权声明:本文博客原创文章,博客,未经同意,不得转载。






本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/4717541.html,如需转载请自行联系原作者


相关文章
|
5月前
|
算法 Windows
class073 背包dp-01背包、有依赖的背包【算法】
class073 背包dp-01背包、有依赖的背包【算法】
41 0
|
7月前
hdoj 2191 背包
虽然每件物品的数目并不是1,可能有多个,但我们完全可以把这个题目转化成01背包来解决。 可以把多件相同的物品合并成一件,马上就变01背包了。
21 0
|
7月前
hdoj 3466 Proud Merchants(01背包)
想想我们为什么要排序, 举个简单的例子,如果数据中出现这样到情况 5 9 3、 6 6 5、5 6 3…… 对5 9 3 处理的时候他只能求出dp[9]然后6 6 5只能在dp[9]的基础上继续处理,它要用到dp[6]、dp[7]……,而这些全是零,但这些一直会是0吗?不是在处理5 6 3的时候可以得到这些值,但6 6 5已经被处理了,它再也不会用的这些了,所以怎么得到正确的结果? 如果我们对5 6 3优先处理就不会出现这样到情况了。
16 0
|
7月前
|
BI
poj 1976 A Mini Locomotive(01背包)
题目的大概意思就是说给你n个数,然后就是有三辆货车头可以拉连续k辆车厢,问你这三个火车头最终可以拉的最大的乘客数是多少。
24 0
|
7月前
light oj 1231-1232 - 1233- Coin Change 背包
暂时到半懂不懂也没办法讲明白,就不误人子弟了,直接贴代码了。
21 0
codeforces292——D. Connected Components(并查集+前缀和优化)
codeforces292——D. Connected Components(并查集+前缀和优化)
77 0
codeforces292——D. Connected Components(并查集+前缀和优化)
|
机器学习/深度学习
HDOJ(HDU) 2083 简易版之最短距离(中位数)
HDOJ(HDU) 2083 简易版之最短距离(中位数)
117 0
HDOJ 2076 夹角有多大(题目已修改,注意读题)
HDOJ 2076 夹角有多大(题目已修改,注意读题)
79 0

热门文章

最新文章