HDU 4044 GeoDefense

树形DP,和背包差不多。dp[now][x]表示now这个节点的子树上,花费为x的时候,获得的最大防御能力(保证敌方HP<=0)

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;

const int maxn = 1000 + 10;
int T, n, m;
vector<int>tree[maxn];
struct kind
{
    int price;
    int power;
    kind(int a, int b){ price = a; power = b; }
};
vector<kind>v[maxn];
bool vis[maxn];
int dp[maxn][200 + 10];
int flag[200 + 10], tmp[200 + 10];

void init()
{
    for (int i = 0; i <= n; i++) tree[i].clear();
    for (int i = 0; i <= n; i++) v[i].clear();
    memset(vis, 0, sizeof vis);
    memset(dp, -1, sizeof dp);
}

void read()
{
    scanf("%d", &n);
    for (int i = 1; i <= n - 1; i++)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        tree[u].push_back(v);
        tree[v].push_back(u);
    }
    scanf("%d", &m);

    for (int i = 1; i <= n; i++)
    {
        int ki;
        scanf("%d", &ki);
        while (ki--)
        {
            int pricei, poweri;
            scanf("%d%d", &pricei, &poweri);
            kind k(pricei, poweri);
            v[i].push_back(k);
        }
    }
}

void dfs(int now)
{
    bool fail = 1;
    for (int i = 0; i<tree[now].size(); i++)
        if (!vis[tree[now][i]]) fail = 0;

    if (fail)
    {
        for (int i = 0; i<v[now].size(); i++)
            dp[now][v[now][i].price] = max(dp[now][v[now][i].price], v[now][i].power);
        return;
    }

    bool d[maxn];
    memset(d, 0, sizeof d);
    for (int i = 0; i<tree[now].size(); i++)
    {
        if (vis[tree[now][i]]) continue;

        int id = tree[now][i];
        vis[id] = 1; dfs(id); d[i] = 1;
    }

    memset(flag, -1, sizeof flag);

    bool first = 1;

    for (int i = 0; i<tree[now].size(); i++)
    {
        if (!d[i]) continue;

        int id = tree[now][i];

        if (first)
        {
            first = 0;
            for (int j = 0; j <= m; j++) flag[j] = dp[id][j];
        }

        else
        {
            memset(tmp, -1, sizeof tmp);
            for (int j = 0; j <= m; j++)
                for (int k = 0; k <= m; k++)
                    if (dp[id][j] != -1 && flag[k] != -1 && j + k <= m)
                        tmp[j + k] = max(tmp[j + k], min(dp[id][j], flag[k]));
            for (int j = 0; j <= m; j++) flag[j] = tmp[j];
        }
    }

    for (int i = 0; i<v[now].size(); i++)
        for (int j = m; j >= v[now][i].price; j--)
            if (flag[j - v[now][i].price] != -1)
                dp[now][j] = max(dp[now][j], flag[j - v[now][i].price] + v[now][i].power);

    for (int i = 0; i <= m; i++) dp[now][i] = max(dp[now][i], flag[i]);

    for (int i = 0; i<v[now].size(); i++)
        dp[now][v[now][i].price] = max(dp[now][v[now][i].price], v[now][i].power);
}

void work()
{
    vis[1] = 1;
    dfs(1);
    int ans = 0;
    for (int i = 0; i <= m; i++) ans = max(ans, dp[1][i]);
    printf("%d\n", ans);
}

int main()
{
    scanf("%d", &T);
    while (T--)
    {
        init();
        read();
        work();
    }
    return 0;
}
时间: 2024-10-06 13:27:29

HDU 4044 GeoDefense的相关文章

hdu 4044 GeoDefense (树形dp+01背包)

GeoDefense Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 663    Accepted Submission(s): 267 Problem Description Tower defense is a kind of real-time strategy computer games. The goal of towe

hdu 4044 GeoDefense(DP-树形DP)

GeoDefense Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 686    Accepted Submission(s): 275 Problem Description Tower defense is a kind of real-time strategy computer games. The goal of towe

HDU 4044 GeoDefense (树形DP,树形背包,混合经典)

题意: 给一棵n个节点的树,点1为敌方基地,叶子结点都为我方阵地.我们可以在每个结点安放炸弹,每点至多放一个,每个结点有ki种炸弹可选,且每种炸弹有一个花费和一个攻击力(1点攻击力使敌人掉1点hp).敌人的目的是我方阵地,任意路线都有可能,但规定只能往下跑.问当有m钱时,最坏情况下最多能打掉敌人多少hp?(n<1001, m<201, ki>=0) 思路: 我竟然自己写出来了,咔咔~证明此题不难! 注意:某些点可能没有炸弹可选(即不能放炸弹):有0花费的炸弹:最坏情况下指的是敌人总是跑攻

HDU ACM 4044 GeoDefense -&gt;树形DP+分组背包

题意:地图是一个编号为1-n的节点的树,节点1是敌方基地,其他叶节点是我方基地.敌人基地会出来敌人,为了防止敌人攻进我方基地,我们可以选择造塔.每个节点只能造一个塔,节点i有ki种塔供选择,价值和攻击力为price_i, power_i,攻击力power_i是让敌人经过这个节点时让敌人的HP减少power_i点.因此从敌人基地到我方任意一个基地的路径,这条路径上所有塔的攻击力之和,就是这个基地的抵抗力. 敌人攻击路径不确定,为了保护我方所有基地,需要确定所有基地中抵抗力最低的一个.我方只有数量为

hdu 4044 2011北京赛区网络赛E 树形dp ****

专题训练 1 #include<stdio.h> 2 #include<iostream> 3 #include<string.h> 4 #include<algorithm> 5 using namespace std; 6 const int MAXN=1010; 7 const int INF=0x3fffffff; 8 struct Node 9 { 10 int to; 11 int next; 12 }edge[MAXN*2]; 13 int t

【转】【DP_树形DP专辑】【9月9最新更新】【from zeroclock&#39;s blog】

树,一种十分优美的数据结构,因为它本身就具有的递归性,所以它和子树见能相互传递很多信息,还因为它作为被限制的图在上面可进行的操作更多,所以各种用于不同地方的树都出现了,二叉树.三叉树.静态搜索树.AVL树,线段树.SPLAY树,后缀树等等.. 枚举那么多种数据结构只是想说树方面的内容相当多,本专辑只针对在树上的动态规划,即树形DP.做树形DP一般步骤是先将树转换为有根树,然后在树上进行深搜操作,从子节点或子树中返回信息层层往上更新至根节点.这里面的关键就是返回的信息部分,这个也没一般性的东西可讲

hdu4044 树形dp+分组背包

http://acm.hdu.edu.cn/showproblem.php?pid=4044 Problem Description Tower defense is a kind of real-time strategy computer games. The goal of tower defense games is to try to stop enemies from reaching your bases by building towers which shoot at them

hdu4044 GeoDefense

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4044 题意:一个树上的塔防游戏.给你n个结点的树,你要在树结点上建塔防御,在第 i 个结点上有 ki 种防御塔可供选择,每个塔给你建塔花费 pricei 和塔能造成的伤害 poweri (可以认为每个塔只能攻击一次),现在有一个怪物从结点1出发,随意的沿着树边去叶子结点,问你最坏的情况最大能对怪物造成多少伤害(即假设怪物会沿着受伤最小的路径走),开始有 m 单位钱 2<=n<=1000, 0<

HDU 6203 ping ping ping [LCA,贪心,DFS序,BIT(树状数组)]

题目链接:[http://acm.hdu.edu.cn/showproblem.php?pid=6203] 题意 :给出一棵树,如果(a,b)路径上有坏点,那么(a,b)之间不联通,给出一些不联通的点对,然后判断最少有多少个坏点. 题解 :求每个点对的LCA,然后根据LCA的深度排序.从LCA最深的点对开始,如果a或者b点已经有点被标记了,那么continue,否者标记(a,b)LCA的子树每个顶点加1. #include<Bits/stdc++.h> using namespace std;