您的位置:首页 > Web前端

HDU 4939-E - Stupid Tower Defense-DP

2016-03-20 11:22 459 查看
题意:

题意:给出一条长为n个单位长度的直线,每通过一个单位长度需要t秒。

有3种塔,红塔可以在当前格子每秒造成x点伤害,绿塔可以在之后的格子每秒造成y点伤害,蓝塔可以使通过单位长度的时间增加z秒。问如何安排3种塔的顺序使得造成的伤害最大,输出最大伤害值

显然 红塔放在最后面是最优的,因此可以枚举i,红塔的位置就是i+1到n

那么只是看前面怎么选蓝和绿

dp[i][j]表示前面i个塔选j个蓝

我们考虑位置J放不放蓝塔时,从1到j的总伤害 //注意特判一下j=0,访问j-1会越界

__int64 tmp1=dp[i-1][j-1]+(i-j)*y*(t+(j-1)*z);  //j is blue时,在第j造成的伤害 +前i-1的伤害
__int64 tmp2=dp[i-1][j]+(i-1-j)*y*(t+j*z);
//j is green,在第j造成的伤害+前i-1的伤害
dp[i][j]=max(tmp1,tmp2);

然后前i个塔里选j个蓝的方案下,我们可以得到最终包括红塔的总伤害 为:

ans=max(ans,dp[i][j]+(n-i)*x*(t+j*z)+(n-i)*(t+j*z)*(i-j)*y);//总伤害,并更新ans

注意dp【i】【j】的i从1开始的话,至少选了1个非红塔,因此记得加上 全选红塔的情况

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

const double pi=acos(-1.0);
double eps=0.000001;

__int64 max(__int64 a,__int64 b)
{return a<b?b:a;}
__int64 dp[1505][1505];
int main()
{
int test;
cin>>test;
__int64 i,j;
int cnt=1;
__int64 x,y,z,t,n;
while(test--)
{
scanf("%I64d%I64d%I64d%I64d%I64d",&n,&x,&y,&z,&t);
memset(dp,0,sizeof(dp));
//dp[i][j] i+1到n是红,前i个里面放了j个蓝ta,i-j个绿
__int64 ans=t*x*n;
for (i=1;i<=n;i++)
{
for (j=0;j<=i;j++)
{
if (j==0)
dp[i][j]=dp[i-1][j]+(i-1-j)*y*t;
else
{
__int64 tmp1=dp[i-1][j-1]+(i-j)*y*(t+(j-1)*z); //j is blue时,在第j造成的伤害
__int64 tmp2=dp[i-1][j]+(i-1-j)*y*(t+j*z); //j is green,在第j造成的伤害
dp[i][j]=max(tmp1,tmp2);
}
ans=max(ans,dp[i][j]+(n-i)*x*(t+j*z)+(n-i)*(t+j*z)*(i-j)*y);//总伤害,并更新ans
}
}

printf("Case #%d: %I64d\n",cnt++,ans);
}
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: