Stupid Tower Defense
Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1181 Accepted Submission(s): 346
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.
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)
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 重点在于把三个要素巧妙转换成2个!#include<stdio.h> #include<string.h> #include<math.h> #include<string> #include<iostream> #include<algorithm> #include<vector> #include<queue> #include<list> #include<map> #include<set> using namespace std; int n,x,y,z,pertime; typedef long long LL; LL dp[1510][1510]; void work(){ memset(dp, 0, sizeof(dp)); LL redgoal,tp; LL ans =1LL * n * pertime * x; // 全部是red ; for(int i = 1 ; i <= n ; i ++){ for(int bn = 0; bn <= i; bn ++){ if(i - 1 >= bn){ // 第 i 个格子建的是 green 塔; dp[i][bn] = dp[i - 1][bn] + 1LL * (n - i) * (pertime + bn * z) * y; // 这个塔的后面有 n - i 个格子,当前时间为 t+bn*z 分数为 y; redgoal = 1LL * (n - i) * x * (pertime + bn * z); ans = max(ans , dp[i][bn] + redgoal); ; } if(bn > 0){ //第i位置建立的是blue, 前面有 i - bn 个 green 在 第 i 个格子 // 之后(n - i )的收益将增加 y * z *(n - i); tp = dp[i - 1][bn - 1] + 1LL * (i - bn) * (n - i) * z * y; redgoal = 1LL * (n - i) * x * (pertime + bn * z); ans = max(ans, tp + redgoal); dp[i][bn] = max(dp[i][bn], tp); } } } cout << ans << endl; } int main() { // freopen("in.in","r",stdin); int T; scanf("%d",&T); for(int ca = 1; ca <= T; ca ++){ scanf("%d%d%d%d%d",&n, &x, &y, &z, &pertime); printf("Case #%d: ",ca); work(); } return 0; }