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. ExtendHelper

    public static class ExtendHelper { /// <summary> /// 检查当前字符串是否符合某种格式 /// </summary> /// ...

  2. Web性能

    使用Web性能测试可以很容易地创建一组可重复的测试,从而帮助我们分析web应用程序的性能,找到性能瓶颈. Web性能测试可以验证一个Web应用程序的行为是否正确.它们会向目标Web应用程序发布一组有序 ...

  3. C#中部分方法返回值类型为什么只能是void?

    这个问题答案选至<C#入门经典> 如果方法具有返回类型,那就可以作为表达式的一部分: x=Manipulate(y,z); 如果没有给部分方法提供实现代码,编译器就会在使用该方法的所有地方 ...

  4. DP入门---Robberies

    HDU  2955 Description The aspiring Roy the Robber has seen a lot of American movies, and knows that ...

  5. 【洛谷 p3368】模板-树状数组 2(数据结构)

    题目:已知一个数列,你需要进行下面两种操作:1.将某区间每一个数数加上x:2.求出某一个数的和. 解法:树状数组+前缀和优化.数组中每位存和前一位的数的差,这样区间修改只用改两位,单点询问就是求前缀和 ...

  6. mac下eclipse的svn(即svn插件)怎么切换账号?

    以mac os x为例(Unix/Linux类似) 打开命令行窗口,即用户的根目录(用户的home目录) cd ~ 即可进入home目录. 执行命令 ls -al 会列出home目录下的所有文件及文件 ...

  7. 解决客户 IE 浏览器"兼容性视图"设置带来的问题

    最近在给客户开发一个 ASP.NET web 报表时,发现客户的 IE8 浏览器上,看网页总是怪怪的. 调查后发现,客户的 IE8 浏览器,统一被设置成"对本地网络使用兼容性视图" ...

  8. 一些实用但不为人知的Unix命令

    浮现在脑海的很多 Linux命令,其中一些不为人知,另一些则很常见,如下: xargs or parallel: 并行运行一些程序,命令有很多的选项 sed and awk: 广为人知并且非常有用的处 ...

  9. DevExpress GridControl使用方法总结

    一.如何解决单击记录整行选中的问题 View->OptionsBehavior->EditorShowMode 设置为:Click 二.如何新增一条记录 (1).gridView.AddN ...

  10. 配置SharePoint使用ADFS

    1. 如果网站应用程序没有使用声明式验证 $wpp = Get-SPWebApplication <URL> $wpp.UseClaimsAuthentication = 1 $wpp.U ...