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,如需转载请自行联系原作者


相关文章
|
4天前
|
算法 Windows
class073 背包dp-01背包、有依赖的背包【算法】
class073 背包dp-01背包、有依赖的背包【算法】
41 0
|
4天前
|
算法 C#
算法系列--动态规划--背包问题(1)--01背包介绍(上)
算法系列--动态规划--背包问题(1)--01背包介绍
22 0
|
4天前
|
机器学习/深度学习 算法 C#
算法系列--动态规划--背包问题(1)--01背包介绍(下)
算法系列--动态规划--背包问题(1)--01背包介绍(下)
20 0
|
7月前
hdoj 2191 背包
虽然每件物品的数目并不是1,可能有多个,但我们完全可以把这个题目转化成01背包来解决。 可以把多件相同的物品合并成一件,马上就变01背包了。
23 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优先处理就不会出现这样到情况了。
18 0
|
7月前
hdoj 1520 Anniversary party(树形dp)
我们可以把一个节点当做一个人,每个节点都有一个权重。按照题目意思,如果我们取了某个节点,那么他的父节点和子节点都是不能取的。按要求选取节点,使得选取节点的权重和最大。
17 0
Codeforces1486 C1.Guessing the Greatest (easy version)(交互题+二分)
Codeforces1486 C1.Guessing the Greatest (easy version)(交互题+二分)
76 0
|
机器学习/深度学习
HDOJ(HDU) 2083 简易版之最短距离(中位数)
HDOJ(HDU) 2083 简易版之最短距离(中位数)
118 0
|
Java
HDOJ1175连连看 DFS
HDOJ1175连连看 DFS
95 0