hdu 4939

Stupid Tower Defense

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 2504    Accepted Submission(s): 712


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
 
析:有一条长n段的路径,为了防御怪兽,需要在每一段路上建塔,塔的类型有3种:
  1.红塔  对当前每个经过的怪兽造成x点伤害
  2.绿塔  对经过绿塔之后的每个位置的怪兽都造成y值伤害
  3.蓝塔  延迟怪兽在每一段路上花费z个时间,若前面经过k个蓝塔,则经过当前塔需要t+k*z时间
  由于红塔为及时伤害,而绿塔为延后伤害,故可知红塔一定放在最后,才能造成更多的伤害,故假设全部建红塔, 用dp[i][j] 表示前i座塔中有j座蓝塔
  第i座塔建绿塔: g = dp[i-1][j-1] + (i-j-1)*(t+z*j)*y
  第i座塔建蓝塔: b = dp[i-1][j] + (i-j)*(t+z*(j-1))*y
  dp[i][j] = max(g, b) , 再加上前面绿塔以及后面红塔对后面的影响即为当前最值
 
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <functional>
#define ll long long
#define ull unsigned ll
#define Inf 0x7fffffff
#define maxn 1000005
#define maxm 100005
#define P pair<int, int>
#define eps 1e-6
#define mod 10000
using namespace std;
const int N = 15005;
int T, n, m, len, ans;
ll t, x, y, z, dp[N][N];

int main(){
    ans = 1;
    scanf("%d", &T);
    while(T--){
        scanf("%d%lld%lld%lld%lld", &n, &x, &y, &z, &t);
        ll res = x*t*n;
        for(ll i = 1; i <= n; i ++){
            for(ll j = 0; j <= i; j ++){
                if(!j){
                    dp[i][j] = dp[i-1][j]+(i-j-1)*(t+j*z)*y;    //建绿塔
                }else{      // 前i座塔中有j座蓝塔
                    ll g = dp[i-1][j]+(i-j-1)*(t+j*z)*y;    //第i座建绿塔
                    ll b = dp[i-1][j-1]+(i-j)*(t+(j-1)*z)*y;//第i座建蓝塔
                    dp[i][j] = max(g, b);
                }
                res = max(res, dp[i][j]+(y*(i-j)+x)*(t+z*j)*(n-i)); //加上后面红塔以及前面绿塔的影响
            }
        }
        printf("Case #%d: %lld
", ans++, res);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/microcodes/p/12787829.html