HDU 4044 GeoDefense(动态规划)
GeoDefense
Time Limit: 12000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 745 Accepted Submission(s): 307

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.
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.
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
70
80
题目输入描述:
有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(动态规划)的更多相关文章
- hdu 4044 GeoDefense (树形dp | 多叉树转二叉树)
题目链接:hdu-4044 题意 这是一个塔防游戏,地图是一个n个编号为1-n的节点的树, 节点1是敌人的基地,其他叶子节点都是你的基地. 敌人的基地会源源不断地出来怪兽,为了防止敌人攻进你的基 ...
- HDU 4044 GeoDefense
树形DP,和背包差不多.dp[now][x]表示now这个节点的子树上,花费为x的时候,获得的最大防御能力(保证敌方HP<=0) #include<cstdio> #include& ...
- HDU 4044 GeoDefense (树形DP,混合经典)
题意: 给一棵n个节点的树,点1为敌方基地,叶子结点都为我方阵地.我们可以在每个结点安放炸弹,每点至多放一个,每个结点有ki种炸弹可选,且每种炸弹有一个花费和一个攻击力(1点攻击力使敌人掉1点hp). ...
- hdu 4044 树形DP 炮台打怪 (好题)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4044 题目大意:给定n个节点组成的树,1为敌方基地,叶子结点为我方结点.我们可以在每个结点安放炮台,至 ...
- [HDU 3535] AreYouBusy (动态规划 混合背包 值得做很多遍)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3535 题意:有n个任务集合,需要在T个时间单位内完成.每个任务集合有属性,属性为0的代表至少要完成1个 ...
- [HDU 1114] Piggy-Bank (动态规划)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1114 简单完全背包,不多说. #include <cstdio> #include < ...
- [HDU 2955]Robberies (动态规划)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955 题意是给你一个概率P,和N个银行 现在要去偷钱,在每个银行可以偷到m块钱,但是有p的概率被抓 问 ...
- HDU 2571 命运 动态规划
命运 http://acm.hdu.edu.cn/showproblem.php?pid=2571 Problem Description 穿过幽谷意味着离大魔王lemon已经无限接近了!可谁能想到, ...
- HDU 5481 Desiderium 动态规划
Desiderium Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=548 ...
随机推荐
- Spring应用——对 JDBC 的支持
一.说明 1.Spring JDBC 对原始的 JDBC 进行了封装,使其更加易用. 2.JdbcTemplate 作为 Spring JDBC 的核心,为不同类型的 JDBC 操作提供了模板方法. ...
- 用Qt写软件系列三:一个简单的系统工具(上)
导言 继上篇<用Qt写软件系列二:QIECookieViewer>之后,有一段时间没有更新博客了.这次要写的是一个简单的系统工具,需求来自一个内部项目.功能其实很简单,就是查看当前当前系统 ...
- nopcommerce3.5源代码及中文语言包下载地址
nopcommerce3.5源代码下载地址 http://download-codeplex.sec.s-msft.com/Download/SourceControlFileDownload.ash ...
- Unity3D入门基本概念整理
1. (1)在场景中添加资源 只需单击工程视图 (Project View) 中的网格(Mesh)并拖动至层级视图 (Hierarchy) 或场景视图 (Scene View),便可将其添加至场景 ( ...
- 重新想象 Windows 8.1 Store Apps (79) - 控件增强: MediaElement, Frame
[源码下载] 重新想象 Windows 8.1 Store Apps (79) - 控件增强: MediaElement, Frame 作者:webabcd 介绍重新想象 Windows 8.1 St ...
- [moka同学笔记]Yii2.0验证码
1.Model中Code.php <?php /** * Created by PhpStorm. * User: moka同学 * Date: 2016/07/25 * Time: 10:48 ...
- HTML Jquery
在<网页制作Dreamweaver(悬浮动态分层导航)>中,运用到了jQuery的技术,轻松实现了菜单的下拉.显示.隐藏的效果,不必再用样式表一点点地修改,省去了很多麻烦,那么jQuery ...
- [js开源组件开发]图片放大镜
图片放大镜 一般情况下,手机由于屏幕太小,会有图片上看不清的问题,所以我就做了一个放大镜的js效果,支持pc和移动端.它的原理是利用的backgroundsize来实现的,所以你的浏览器首先要支持这个 ...
- 【基础】PHP变量及变量作用域
新学PHP,比较有意思的语法,记录下. 1. 变量的作用域 作用域只分两个Global和Local,Global相对于整个.php文件来讲,Local是本地最小范围,是距离变量最近的范围,如:在函数中 ...
- 用单例模式封装常用方法 utils class v1.0
utils class v1.0:The common methods used in our JS are included. * by sarah on 2016/01/28 var utils ...