hdoj 4939 Stupid Tower Defense 【DP】
2015-10-23 17:03
375 查看
Stupid Tower DefenseTime Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1908 Accepted Submission(s): 531 Problem Description FSF is addicted to a stupid tower defense game. The goal of tower defense games is to try to stop enemies from crossing a map by building traps to slow them down and towers which shoot at them as they pass. The map is a line, which has n unit length. We can build only one tower on each unit length. The enemy takes t seconds on each unit length. And there are 3 kinds of tower in this game: The red tower, the green tower and the blue tower. The red tower damage on the enemy x points per second when he passes through the tower. The green tower damage on the enemy y points per second after he passes through the tower. The blue tower let the enemy go slower than before (that is, the enemy takes more z second to pass an unit length, also, after he passes through the tower.) Of course, if you are already pass through m green towers, you should have got m*y damage per second. The same, if you are already pass through k blue towers, the enemy should have took t + k*z seconds every unit length. FSF now wants to know the maximum damage the enemy can get. Input There are multiply test cases. The first line contains an integer T (T<=100), indicates the number of cases. Each test only contain 5 integers n, x, y, z, t (2<=n<=1500,0<=x, y, z<=60000,1<=t<=3) Output For each case, you should output "Case #C: " first, where C indicates the case number and counts from 1. Then output the answer. For each test only one line which have one integer, the answer to this question. Sample Input 1 2 4 3 2 1 Sample Output Case #1: 12 HintFor the first sample, the first tower is blue tower, and the second is red tower. So, the total damage is 4*(1+2)=12 damage points. |
红塔——敌军通过时,会对他们造成每秒x点伤害
绿塔——敌军通过后,会对他们造成每秒y点的持续伤害(直到走完长度为n的路径)
蓝塔——敌军通过后,会对他们减速,使得他们通过每单位长度的时间延长z s
问你对敌军造成的最大伤害。
思路:考虑把红塔放在最后面的情况,可能在后面放 0-n 个,在这个假设下求出最优解。
用dp[i][j]表示 在我们用过j个蓝塔的前提下 敌军到达第i个单元时 所付出的最大代价,显然0 <= j <= i。
则对dp[i][j],每秒伤害加成cost = (i-j) * y,通过每单元时间加成time = t + j * z。
那么最优解 = max(所有合法的dp[i][j] + (n - i) * (cost + x), dp
[k]其中0 <= k <= n).
我们只需每次由dp[i][j]推出dp[i+1][j+1] 和 dp[i+1][j],然后对dp[i][j]的状态维护最大值。最后求出状态
dp
和 dp
[n-1],在(0 <= k <= n)上维护dp
[k]最大值。
AC代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 1500+1
#define LL long long
using namespace std;
LL dp[MAXN][MAXN];
int k = 1;
void solve()
{
int n;
LL x, y, z, t;
scanf("%d%lld%lld%lld%lld", &n, &x, &y, &z, &t);
memset(dp, 0, sizeof(dp));
LL ans = 0;
for(int i = 0; i < n; i++)
{
for(int j = 0; j <= i; j++)
{
LL time = j * z + t, cost = (i - j) * y;
dp[i+1][j+1] = max(dp[i+1][j+1], dp[i][j] + time * cost);
dp[i+1][j] = max(dp[i+1][j], dp[i][j] + time * cost);
ans = max(ans, dp[i][j] + (n-i) * (x + cost) * time);
}
if(i == n-1)
for(int j = 0; j <= n; j++)
ans = max(ans, dp
[j]);
}
printf("Case #%d: %lld\n", k++, ans);
}
int main()
{
int t;
scanf("%d", &t);
while(t--){
solve();
}
return 0;
}
相关文章推荐
- Angular - Templates(模板)
- jquery动态改变div宽度和高度
- NodeJS 实现基于 token 的认证应用
- 使用jqueryMobile的一些问题
- NVIDIA DIGITS 学习笔记(NVIDIA DIGITS-2.0 + Ubuntu 14.04 + CUDA 7.0 + cuDNN 7.0 + Caffe 0.13.0)
- js 颜色10进制转化成rgba
- ZH奶酪:HTML元素文本溢出显示省略号(...)
- 全面理解面向对象的 JavaScript
- 再谈javascript函数节流
- JavaScript之 ------ 函数(一般函数、动态函数、匿名函数)
- 一天JavaScript示例-判定web页面的区域
- HTML5游戏制作之路_01_白鹭引擎&&相关必要的配置安装&&创建第一个H5项目
- JQuery中动态添加easyui组件 动态渲染 parser具体怎么用
- JSTL标签使用
- Extjs 4.2 comboBox下拉复选框 checkbox
- cordys 前端 HTML 提交流程和接受流程数据
- 使用Javascript 实现 分享到 新浪微博 QQ 空间等
- HTML在线报名
- 字典样式 NSString 转化为 NSDictinary
- .Net转前端