您的位置:首页 > Web前端

hdoj 4939 Stupid Tower Defense 【DP】

2015-10-23 17:03 375 查看

Stupid Tower Defense

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

 

题意:敌军要经过一段n单元的路径。敌军每经过一个单元耗时t s,且我们可以在n单元路径上每单元设置一个塔。

红塔——敌军通过时,会对他们造成每秒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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: