题意:
建塔,有3种选择---红色(对经过的敌人造成x/s的伤害)、绿色(对经过之后的敌人造成全程伤害,伤害值随个数k递增:k*y/s)、蓝色(对经过后的敌人减速,随个数k递增:t+k*z)。
给你可建的塔的个数,红、绿、蓝分别的伤害(x、y、z)以及初始时间t,求敌人得到的最大伤害值。
分析:红色的伤害是固定的,所以必然放在最后面划算,所以可以枚举红色的个数i,前面的n-i个怎么放蓝绿2种用dp求解。dp[i][j]表示前i个塔放了j个蓝塔的最大伤害,那么
dp[i][j]=max(dp[i-1][j-1]+(i-j)*y*(t+z*(j-1)),dp[i-1][j]+(i-j-1)*y*(t+j*z))
则红塔数为n-i时的总伤害dmg=dp[i][j]+(n-i)*x*(t+j*z)+(n-i)*(i-j)*y*(t+j*z),ans=max(dmg,ans)
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
long long dp[1505][1505];
long long n,x,y,z,t,ans;
int main()
{
int T,cas,i,j;
scanf("%d",&T);
for(cas=1;cas<=T;cas++)
{
memset(dp,0,sizeof(dp));
scanf("%I64d%I64d%I64d%I64d%I64d",&n,&x,&y,&z,&t);
ans=n*x*t;//初始值:全放红色
for(i=1;i<=n;i++)
for(j=0;j<=i;j++)
{
if(j==0)dp[i][j]=dp[i-1][j]+(i-j-1)*y*t;
else
{
long long tmp1=dp[i-1][j-1]+(i-j)*y*(t+z*(j-1));//第j个放蓝色
long long tmp2=dp[i-1][j]+(i-j-1)*y*(t+j*z);//第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);//前面放蓝色和绿色的伤害加上后面放红色的伤害
}
printf("Case #%d: %I64d\n",cas,ans);
}
return 0;
}