GeoDefense

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

Total Submission(s): 745    Accepted Submission(s): 307

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 as they pass. 




The choice and positioning of the towers is the essential strategy of the game. Many games, such as Flash Element Tower Defense, feature enemies that run through a "maze", which allows the player to strategically place towers for optimal effectiveness. However,
some versions of the genre force the user to create the maze out of their own towers, such as Desktop Tower Defense. Some versions are a hybrid of these two types, with preset paths that can be modified to some extent by tower placement, or towers that can
be modified by path placement.



geoDefense is a Thinking Man’s Action Tower Defense. It has become one of "PC World's 10 iPhone Games You CANNOT Live Without". Using exciting vectorized graphics, this highly kinetic game brings a whole new dimension to the defense genre. Devastate creeps
with blasters, lasers and missiles and watch their energy debris swirl through the gravity wells of your vortex towers.



There is a geoDefense maze of n points numbered from 1 and connected by passageways. There are at least two dead ends among these n points, and there is always one and only one path between any pair of points. Point 1 is a dead end, and it’s the base of enemies,
and all the other dead ends are your bases.



To prevent the enemy reaching your bases, you have to construct towers to attack the enemy. You can build tower on any point and you can only build one tower on one point. A tower can only shot the enemy when it passes the tower. You are given ki choices to
build tower on point i, and each choice is given in the format of (price, power) which means that you can build a tower with attack power value equals power in the cost of price. You can also build nothing on a point so it will not cost your money. A tower
will reduce the enemy’s HP by its attack power. When the HP is less or equal to zero, the enemy dies immediately. 



The base of enemies will release only one enemy. It moves very fast that you cannot do anything such as building towers while it is running. It runs all the way until it dies or reaches one of your bases. However, you cannot predict the route it will go through.
To win the game, you must kill the enemy before it reaches your bases. You have to strategically place towers for optimal effectiveness so that the fortifications are steady enough to protect the bold and powerful enemy with high HP. You are troubling your
head on figuring out the highest HP of the enemy you are able to kill on the way certainly. You have money m when the game begins.

Please note that the towers build in the enemy’s base or your bases are all effective and if the enemy is shot to death in your bases, you still win.
 
Input
The input consists of several test cases. The first line is an integer T (1 <= T <= 20), which shows the number of the cases.

For each test case, the first line contains only one integer n (2 <= n <= 1000) meaning the number of points. 

The following n-1 lines describe the passageways. Each line contains two integers u and v, which are the endpoints of a passageway. 

The following line contains only one integer m (1 <= m <= 200) meaning the amount of your money when the game begins. 

Then n lines follow. The ith line describes the construction choices of the ith point. It starts with an integer ki (0 <= ki <= 50) and ki is followed by ki pairs of integers separated by spaces. The jth pair is (pricei,j, poweri,j), 0 <= pricei,j <= 200, 0
<= poweri,j <= 50000. ki being zero means that you can’t build a tower on the ith point. 
 
Output
For each test case, output a line containing the highest HP value of your enemy that you can deal with. It means that if your enemy’s HP is larger than that highest value, you can’t guarantee your victory.
 
Sample Input
2
2
1 2
30
3 10 20 20 40 30 50
3 10 30 20 40 30 45
4
2 1
3 1
1 4
60
3 10 20 20 40 30 50
3 10 30 20 40 30 45
3 10 30 20 40 30 35
3 10 30 20 40 30 35
 
Sample Output
70
80
 
Source
 
Recommend
lcy   |   We have carefully selected several similar problems for you:  4050 4042 4047 4048 4040 
 

题目输入描述:

有T组测试数据,每组

首先一个n,表示一颗生成树有n个节点

接下来n-1行表示n-1条边描述这个生成树

接下来一行表示你的总的钱数sum

接下来n行,第i行表示树上的第i号节点可以建 ki 个 塔,每个塔两个数字参数表示花费和造成的伤害。

这是个塔防游戏,敌人从树根(1号节点)出发,叶子节点是你的基地,敌人的路线不固定,经过每个节点的塔后受到伤害

问你在总的花费下,你选择建一些塔,敌人的血量至多是多少才能保证不伤害到你的基地。

解题思路:

这题已经讨论过,用两个DP,也就是DP里面套一个DP,今天思维清晰,实现了,代码100行,超过了正常DP的长度。

有人用树形DP去实现,不管用什么实现,核心思路肯定相像。

(1)首先,可以把这整颗树看成一个问题,就是让这个树要求的那个答案ans最大。

要使 ans 最大,就可以分析一下,我认为ans可以分成两部分

第一部分:这个很简单,就是“树根”造塔产生的花费ci,造成的伤害pi

第二部分:

这个比较复杂,就是树根下有很多子树,也就是敌人可能走任意一条路,很明显敌人会走哪个伤害最小的路。

也就是在剩下的钱数下使得最小的路径的伤害值最大,假设以求出,记为DP2([son],left_money)

综合这个两个部分,所以这颗树的答案ans=DP1(root,sum) = max { pi + DP2([son],sum-ci) }

(2)那么 DP2([son],money)这个怎么求?

这个也很好求,枚举每个son的花费,在所有的花费的情况下求最大,但是儿子之间的伤害取最小。

也就是:DP2([son],money)=DP2(son1,money)

假设第一个儿子花了Ci元,得到的伤害是多少呢?很明显示DP1(son1,Ci)

所以DP2(son1,money)= max{ min( DP1(son1,Ci),DP(son2,money-Ci) ) }

综上,由(1)(2)两个DP可以求出答案也就是调用DP1(1,sum).

解题代码:

#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std; const int maxn=1100; vector <int> g[maxn],path[maxn];
vector < pair<int,int> > v[maxn];
int n,money,next[maxn];
int dp1[maxn][210],dp2[maxn][210],vis1[maxn][210],vis2[maxn][210],mark1,mark2; int DP1(int k,int sum); int DP2(int k,int sum){
if(k==-1) return (1<<30);
if(vis2[k][sum]==mark2) return dp2[k][sum];
int ans=0;
for(int i=0;i<=sum;i++){
int tmp=min(DP1(k,i),DP2(next[k],sum-i));
if(tmp>ans) ans=tmp;
}
vis2[k][sum]=mark2;
return dp2[k][sum]=ans;
} int DP1(int k,int sum){
if(vis1[k][sum]==mark1) return dp1[k][sum];
int ans=0;
for(int i=0;i<v[k].size();i++){
if(sum<v[k][i].first) continue;
int tmp=v[k][i].second;
if(g[k].size()>0) tmp+=DP2(g[k][0],sum-v[k][i].first);
if(tmp>ans) ans=tmp;
}
vis1[k][sum]=mark1;
return dp1[k][sum]=ans;
} void dfs(int u,int fa){
for(int i=0;i<path[u].size();i++){
if(path[u][i]!=fa){
g[u].push_back(path[u][i]);
dfs(path[u][i],u);
}
}
} void init(){
for(int i=0;i<=n;i++){
g[i].clear();
v[i].clear();
path[i].clear();
}
mark1++;
mark2++;
} void input(){
int x,y,q;
for(int i=1;i<n;i++){
scanf("%d%d",&x,&y);
path[x].push_back(y);
path[y].push_back(x);
}
scanf("%d",&money);
for(int i=1;i<=n;i++){
scanf("%d",&q);
v[i].push_back(make_pair(0,0));
while(q-- >0){
scanf("%d%d",&x,&y);
v[i].push_back(make_pair(x,y));
}
}
dfs(1,-1);
for(int i=1;i<=n;i++){
for(int j=1;j<g[i].size();j++){
next[g[i][j-1]]=g[i][j];
}
if(g[i].size()>0) next[g[i].back()]=-1;
}
} void solve(){
printf("%d\n",DP1(1,money));
} int main(){
int T;
scanf("%d",&T);
for(int t=0;t<T;t++){
scanf("%d",&n);
init();
input();
solve();
}
return 0;
}

版权声明:欢迎关注我的博客,本文为博主toyking原创文章,未经博主允许不得转载。

HDU 4044 GeoDefense(动态规划)的更多相关文章

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

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

  2. HDU 4044 GeoDefense

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

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

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

  4. hdu 4044 树形DP 炮台打怪 (好题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4044 题目大意:给定n个节点组成的树,1为敌方基地,叶子结点为我方结点.我们可以在每个结点安放炮台,至 ...

  5. [HDU 3535] AreYouBusy (动态规划 混合背包 值得做很多遍)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3535 题意:有n个任务集合,需要在T个时间单位内完成.每个任务集合有属性,属性为0的代表至少要完成1个 ...

  6. [HDU 1114] Piggy-Bank (动态规划)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1114 简单完全背包,不多说. #include <cstdio> #include < ...

  7. [HDU 2955]Robberies (动态规划)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955 题意是给你一个概率P,和N个银行 现在要去偷钱,在每个银行可以偷到m块钱,但是有p的概率被抓 问 ...

  8. HDU 2571 命运 动态规划

    命运 http://acm.hdu.edu.cn/showproblem.php?pid=2571 Problem Description 穿过幽谷意味着离大魔王lemon已经无限接近了!可谁能想到, ...

  9. HDU 5481 Desiderium 动态规划

    Desiderium Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=548 ...

随机推荐

  1. 数据库中触发器before与after认识

    Before与After区别: before:(insert.update)可以对new进行修改,after不能对new进行修改,两者都不能修改old数据. 对于INSERT语句, 只有NEW是合法的 ...

  2. 解决PL/SQL查询结果乱码的问题

    首选查询oracle服务端的编码,然后将客户端NLS_LANG设置成和Oralce服务端一样的编码即可. 1.检查服务器编码: 执行SQL语法: select * from v$nls_paramet ...

  3. iis7.5错误 配置错误

    iis7.5详细错误   HTTP 错误 500.19 - Internal Server Error无法访问请求的页面,因为该页的相关配置数据无效. 详细错误信息模块 IIS Web Core 通知 ...

  4. 一个Linq表达式的扩展函数帮助类

    /// <summary> /// Linq表达式的扩展函数 /// </summary> public static class ExpressionExtensions { ...

  5. 安装win8、ubuntu双系统的过程

    弄了一个晚上,终于完成了,之前是用虚拟机的,但是觉得不带劲,并且折腾来时菜鸟变大神的捷径,虽然现在还一直在爬坑.继续奋斗吧...王小二 首先是看 ubuntu 百度贴吧的安装帖子(http://tie ...

  6. Mysql –>EF edmx(model first)–> Sql server table

    一.mysql environment When we create an new database,first We need draw er diagram for somebody to sho ...

  7. C#的pictureBox怎样使用多张图片简单切换

    首先,先创建一个新的winform项目ImageTest,选择窗体,起名我ImageForm,在ImageForm拉一个picturebox控件,一个控制器trimer,一个相册imageList,在 ...

  8. json format validator

    http://la5u.org/archives/542 http://stedolan.github.io/jq/download/ https://linuxtoy.org/archives/jq ...

  9. The type java.util.Map$Entry cannot be resolved. It is indirectly referenced。。.相似的错误

    这个问题是出现一般都是因为JDK版本的问题.今天公司安装NC的时候就出现了这个问题.经过对错误的分析和猜测,将JDK从1.8i换成了1.7,之后就行了.根据我个人的猜测,可能是1.8以后就不支持Map ...

  10. bzoj1146整体二分+树链剖分+树状数组

    其实也没啥好说的 用树状数组可以O(logn)的查询 套一层整体二分就可以做到O(nlngn) 最后用树链剖分让序列上树 #include<cstdio> #include<cstr ...