HDU 4939 Stupid Tower Defense(dp)

时间:2023-03-09 01:31:25
HDU 4939 Stupid Tower Defense(dp)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4939

解题报告:一条长度为n的线路,路上的每个单元格可以部署三种塔来给走在这条路上的敌人造成伤害,第一种塔只给在这个塔的范围内的敌人每秒造成x点的伤害,第二种塔给已经经过过这个塔的敌人每秒造成y点伤害,第三种塔能使已经经过了这个塔的敌人的前进的速度减慢,具体效果是,原来敌人经过一个单元格的时间是t秒,经过减速后,经过每个单元格的时间是t + z,这个一个塔减速的效果,减速的效果可以叠加,同样,第二种塔的伤害的效果也可以叠加,每个单元格只能放一个塔。

dp[i][j]表示的是前i个放的是绿塔或蓝塔,到第i个单元格的最大伤害,然后递推公式是:

dp[i][j] = max(dp[i-1][j] + (i-j-1)*(j*z+t)*y  ,dp[i-1][j-1] +(i-j)*((j-1)*z+t)*y);

最后加上后面n-i个的伤害,后面n-i个就是全部放第一种塔了。

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL __int64
LL dp[][]; LL n,x,y,z,t; int main()
{
int T,kase = ;
scanf("%d",&T);
while(T--)
{
scanf("%I64d%I64d%I64d%I64d%I64d",&n,&x,&y,&z,&t);
memset(dp,,sizeof(dp));
LL ans = n * x * t;
for (int i = ; i <= n; ++i)
{
dp[i][] = dp[i-][] + t * (i - ) * y;
ans=max(ans,dp[i][] + t*y*(n - i)*i + x*(n - i)*t);
}
for(int i = ;i <= n;++i)
for(int j = ;j <= i;++j)
if(i == j) dp[i][j] = ;
else dp[i][j] = max(dp[i-][j] + (i--j)*y*(j*z+t),dp[i-][j-] + y * (i - j) * ((j-) * z + t));
for(int i = ;i <= n;++i)
for(int j = ;j <= i;++j)
{
dp[i][j] += ((n-i)*x*(j * z + t) + (n-i)*(i-j)*(j*z+t)*y);
ans = dp[i][j] > ans? dp[i][j]:ans;
}
printf("Case #%d: %I64d\n",kase++,ans);
}
return ;
}
/*
10
4 1 1 1 1
Case #1: 9
1 3 10 3 1
Case #2: 0
3 1 10 1 3
Case #3: 74
*/