首页 > 代码库 > hdu4939 Stupid Tower Defense (DP)
hdu4939 Stupid Tower Defense (DP)
2014多校7 第二水的题
4939
Stupid Tower DefenseTime Limit: 12000/6000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 366 Accepted Submission(s): 88Problem 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 12 4 3 2 1 Sample Output Case #1: 12 Hint For 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.Author UESTC Source 2014 Multi-University Training Contest 7 Recommend We have carefully selected several similar problems for you: 4944 4943 4942 4941 4940 |
题意:塔防,怪过每个块用的初始时间为t。每块可以建一个塔,有三种塔,一种是红塔,怪经过当前格子时每秒输出x;一种绿塔,怪过了当前格子后每秒被毒y血;一种是蓝塔,怪经过当前格子后经过每格的时间增加z秒。绿塔和蓝塔效果都可叠加,求最高输出。
题解:DP。
思考题面,可以想到红塔放最后是最优解,可以反证得:如果有个红塔后面有个不红的塔,交换它们肯定可以得更优解。
这样我们就枚举不红的塔的数量、绿塔的数量,f[i][j]表示有前面有i个不红的塔,其中绿塔有j个时,蓝绿塔在全路段的输出和。
因为已知i,j时,后面的红塔的输出也是固定的(只随着i,j变化,ij固定时红塔输出不变),所以我们dp求得各种ij的最大的f[i][j],ans每次更新。
由于数好像有点大,用超碉的会滚的队列比较爽。
1 //#pragma comment(linker, "/STACK:102400000,102400000") 2 #include<cstdio> 3 #include<cmath> 4 #include<iostream> 5 #include<cstring> 6 #include<algorithm> 7 #include<cmath> 8 #include<map> 9 #include<set>10 #include<stack>11 #include<queue>12 using namespace std;13 #define ll long long14 #define usll unsigned ll15 #define mz(array) memset(array, 0, sizeof(array))16 #define minf(array) memset(array, 0x3f, sizeof(array))17 #define REP(i,n) for(i=0;i<(n);i++)18 #define FOR(i,x,n) for(i=(x);i<=(n);i++)19 #define RD(x) scanf("%d",&x)20 #define RD2(x,y) scanf("%d%d",&x,&y)21 #define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)22 #define WN(x) prllf("%d\n",x);23 #define RE freopen("D.in","r",stdin)24 #define WE freopen("1biao.out","w",stdout)25 ll max(ll x,ll y) {26 return x>y?x:y;27 }28 ll f[2][1555][1555];///green blue29 30 int main() {31 ll T,cas=1;32 ll n,t;33 ll x,y,z;34 ll now,pre;35 ll i,j,k;36 scanf("%I64d",&T);37 while(T--) {38 scanf("%I64d%I64d%I64d%I64d%I64d",&n,&x,&y,&z,&t);39 memset(f,0,sizeof(f));40 now=0;41 pre=1;42 ll ans=x*t*n;43 for(i=1; i<=n; i++) { ///第1到第i个不放红的44 for(j=0; j<=i; j++) { ///第1个到第i个有j个green45 k=i-j;///第1个到第i个有k个blue46 if(k>0) {///第i个放蓝的47 f[now][j][k]=f[pre][j][k-1] + j*y*z*(n-i);///放这个蓝的接下来n-i格每格增加了z时间48 }49 if(j>0) {///放绿的50 f[now][j][k]=max(f[now][j][k],f[pre][j-1][k] + y*(t+k*z)*(n-i) );///放这个绿的每秒增加y伤害51 }52 ans=max(ans,f[now][j][k] + x*(n-i)*(t+k*z));53 }54 pre=now;55 now^=1;56 }57 printf("Case #%I64d: %I64d\n",cas++,ans);58 }59 return 0;60 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。