题目链接:hdu 4939 Stupid Tower Defense
题目大意:塔防游戏,一个长度为n的路,给定x,y,z和t。然后对应每个长度的位置可以放攻击塔,有三种:
- 红塔:怪在红塔所单位长度内每秒受到x点伤害。
- 绿塔:怪经过绿塔之后,每秒受到y点伤害。
- 蓝塔:怪经过后每走一格的时间加上z。
求最大伤害。
解题思路:更具塔的性质,红塔肯定放在最后,所以有dp[i][j]表示到第i个位置,放j个蓝塔造成的伤害值最大为多少。并且过程中维护ans最大(要加上后面红塔的攻击伤害),对于一个状态dp[i][j],除了转移到dp[i+1][j]和dp[i+1][j+1]之外,可以将后面n-i个位置视为放红塔,去维护ans。
逆推的时候注意一下边界,还有初始化的时候别忘了全放红塔的特殊情况。
#include<iostream>
#include<stdio.h>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
long long dp[2000][2000];
int main()
{
long long T,num=0;
cin>>T;
while(T--)
{
num++;
long long n,x,y,z,t,ans;
memset(dp,0,sizeof(dp));
cin>>n>>x>>y>>z>>t;
ans=n*t*x;//!!!!!!!!!!!!!!!!
for(long long i=1;i<=n;i++)
for(long long j=0;j<=i;j++)
{
if(j==0) dp[i][j]=dp[i-1][j]+(i-1-j)*y*(t+z*j);
else
dp[i][j]=max(dp[i-1][j-1]+(i-j)*y*(t+z*(j-1)),dp[i-1][j]+(max(i-1-j,0LL))*y*(t+z*j));// Attention!
ans=max(dp[i][j]+(n-i)*(t+z*j)*(x+(i-j)*y),ans);
}
cout<<"Case #"<<num<<": "<<ans<<endl;
}
while(1);
return 0;
}