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

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

2<=n<=1000, 0<=ki<=50, 0<=pricei<=200, 0<=poweri<=5e4, 0<=m<=200

题解:树形dp,f[u][x]表示在以 u 为根的子树上花费 x 最多造成 f[u][x] 的伤害

考虑状态转移,对于当前结点u他有儿子 v1,v2,,,,vt,你现在有 x 单位钱,如何给这 t 个儿子分配使得伤害最小的儿子伤害最高?

依次遍历儿子,用maxSon[y]表示给到当前儿子为止总共花 y 单位钱,获得的最大收益

时间复杂度:O(n*m^2)

 /*
* Problem:
* Author: SHJWUDP
* Created Time: 2015/10/6 星期二 22:57:51
* File Name: 1001.cpp
* State:
* Memo:
*/
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm> using namespace std; const int INF=0x7f7f7f7f; struct Graph {
struct Edge {
int u, v;
};
int n, m;
vector<Edge> edges;
vector<vector<int>> G;
vector<vector<pair<int,int>>> tower;
vector<vector<int>> f;
Graph(int _n):n(_n),m(),G(_n),tower(n),f(n){}
void addEdge(int u, int v) {
edges.push_back({u, v});
m=edges.size();
G[u].push_back(m-);
}
vector<int> & operator[](int x) {
return G[x];
}
}; int n, m;
void dfs(Graph & G, int u, int fa) {
auto & tower=G.tower[u];
auto & bag=G.f[u];
bag.assign(m+, );
for(const auto & p : tower) {
if(p.first>m) continue;
bag[p.first]=max(bag[p.first], p.second);
}
if(G[u].size()== && u!=) return;
vector<int> maxSon(m+, INF);
for(auto i : G[u]) {
const auto & e=G.edges[i];
if(e.v==fa) continue;
dfs(G, e.v, u);
const auto & vbag=G.f[e.v];
for(int j=m; j>=; --j) {
int mx=;
for(int k=; k<=j; ++k) {
mx=max(mx, min(maxSon[j-k], vbag[k]));
}
maxSon[j]=mx;
}
}
for(int v=m; v>=; --v) {
for(int i=; i<=v; ++i) {
if(maxSon[i]==INF) continue;
bag[v]=max(bag[v], bag[v-i]+maxSon[i]);
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in", "r", stdin);
//freopen("out", "w", stdout);
#endif
int T;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
Graph tree(n);
for(int i=; i<n-; ++i) {
int a, b;
scanf("%d%d", &a, &b);
--a; --b;
tree.addEdge(a, b);
tree.addEdge(b, a);
}
scanf("%d", &m);
for(int i=; i<n; ++i) {
int num;
scanf("%d", &num);
tree.tower[i].resize(num);
for(auto & p : tree.tower[i]) {
scanf("%d%d", &p.first, &p.second);
}
}
dfs(tree, , -);
int ans=;
for(auto x : tree.f[]) ans=max(ans, x);
printf("%d\n", ans);
}
return ;
}

hdu4044 GeoDefense的更多相关文章

  1. HDU4044 GeoDefense(有点不一样的树上背包)

    题目大概说一棵n个结点的树,每个结点都可以安装某一规格的一个塔,塔有价格和能量两个属性.现在一个敌人从1点出发但不知道他会怎么走,如果他经过一个结点的塔那他就会被塔攻击失去塔能量的HP,如果HP小于等 ...

  2. HDU 4044 GeoDefense(动态规划)

    GeoDefense Time Limit: 12000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  3. hdu 4044 GeoDefense (树形dp | 多叉树转二叉树)

    题目链接:hdu-4044 题意 这是一个塔防游戏,地图是一个n个编号为1-n的节点的树, 节点1是敌人的基地,其他叶子节点都是你的基地.    敌人的基地会源源不断地出来怪兽,为了防止敌人攻进你的基 ...

  4. HDU 4044 GeoDefense

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

  5. hdu4044

    题意:给你一颗树有n个节点,树的根节点为1,表示为敌人的基地,其他叶子节点为你的基地,你一开始有m元,给你每个节点可以建造的塔的数量和塔的价格和可以照成的伤害,每个节点至多建立一座塔.敌人的基地每次会 ...

  6. hdu4044 依赖背包变形 好题!

    由于不是求最大的可拦截的HP值,而是要将最小值最大化,那么就需要分配每个子树用的钱数以达到最小值最大化 第一步解决如何分配钱使得结点u的子树中用了j元钱后可以拦截的HP最大,这就是变形的分组(依赖)背 ...

  7. HDU 4044 GeoDefense (树形DP,混合经典)

    题意: 给一棵n个节点的树,点1为敌方基地,叶子结点都为我方阵地.我们可以在每个结点安放炸弹,每点至多放一个,每个结点有ki种炸弹可选,且每种炸弹有一个花费和一个攻击力(1点攻击力使敌人掉1点hp). ...

  8. HDU-4044 树形背包dp好题

    不会做,题解是参考网上的.感觉这道题是到好题,使得我对树形背包dp更了解了. 有几个注意的点,直接给出代码,题解以及注意点都在注释里了. #include<bits/stdc++.h> u ...

  9. [POJ&HDU]杂题记录

    POJ2152 树形dp,每次先dfs一遍求出距离再枚举所有点转移即可. #include<iostream> #include<cstdio> #include<cma ...

随机推荐

  1. 修改目的端trail文件的最大大小--转载

    本文为原创,转载请注明出处: http://blog.csdn.net/msdnchina/article/details/38346435 修改目的端trail文件的最大大小. 本文产生的背景: 在 ...

  2. mysql分组函数

    组函数针对的是指定字段的非空值.注意:where子句中不能出现组函数!!! avg()    平均值(只能针对数值型 ) max()    最大值(不限制类型) min()    最小值(不限制类型) ...

  3. 监听自定义ItemRender的事件

    <mx:Repeater id="rp" dataProvider="{_layersInfo}">    <mx:VBox label=&q ...

  4. HandlerThread和IntentService

    HandlerThread 为什么要使用HandlerThread? 我们经常使用的Handler来处理消息,其中使用Looper来对消息队列进行轮询,并且默认是发生在主线程中,这可能会引起UI线程的 ...

  5. Axure 7.0 正式版 + 汉化包 安装

    详情如下: Axure 7.0 正式版终于发布了,现在提供简体中文版给大家使用. Axure 7.0 正式版: 链接: http://pan.baidu.com/s/1kV4OJ47 提取密码: be ...

  6. es6 Class的继承extends & super

    Class之间可以通过extends关键字,实现继承. 子类会继承父类的属性和方法. class Point { constructor(x, y) { this.x = x; this.y = y; ...

  7. What's going on in background?

    Did you know that mobile phone manufacturer collect your info without notifying you? Did you know yo ...

  8. Java基础--定时任务Timer

    Java基础--定时任务Timer 一.Timer介绍 java.util.Timer java.util.TimerTask Timer是一个定时器类,通过该类可以为指定的定时任务进行配置.Time ...

  9. 数据库的NULL值讨论

    有许多关于数据库设计中NULL的讨论,我个人的设计习惯是,不使用NULL值. 我所设计所有表都是Not Null的字段的,尤其是我主要做数据仓库的表设计.刚开始使用数据库时,就栽了一次.一个Group ...

  10. 游戏笔记之《Fez》

    FEZ 游戏名称:菲斯 英文名称:Fez 游戏类型:ACT(动作游戏),AVG(冒险游戏) 游戏制作:Polytron Corporation 游戏发行:Trapdoor 游戏平台:PC 游戏画面: ...