hdoj 4939 Stupid Tower Defense【dp】

来源:互联网 发布:智器PDF阅读软件 编辑:程序博客网 时间:2024/06/05 20:20

题目:hdoj 4939 Stupid Tower Defense点击打开链接


来源:2014 Multi-University Training Contest 7


题意:塔防游戏,让你在一条直线上规划塔的放法,对经过的怪伤害最大,有三种类型的塔,第一种红塔,对经过的怪每一秒伤害x,第二种绿塔,对经过它之后的怪每秒伤害y,但是每增加一个绿塔伤害加 y,即第k个伤害 k* y ,然后第三种蓝塔,对经过的怪延时 z ,初始时经过一个单位的塔时间是t分钟,第 k 个延时 (t+k*z),求最大伤害。


分析:分析发现蓝塔和绿塔是随着放的数量的增多呈线性增长的,而红塔伤害不便,那么我把红塔放在最后段是最优,如果红塔的伤害足够高,也有可能全部放红塔,那么我们可以先 规划 出绿塔和蓝塔的放法,最后再枚举最后放几个红塔最好。


定义dp【i】【j】:在前 i 个位置放 j 个延时塔的最大伤害,那么对于当前塔,只有两种放法,要么绿塔,要么蓝塔。

则定义转移方程:dp【i】【j】= max(dp【i-1】【j】+( i - j - 1 )* y *(t +(z * j))(放绿塔),dp【i-1】【j-1】+ (i - j )* y *(t+(j-1)*z))(放蓝塔);


而对于红塔的数量,只用维护一个ans = max(ans,dp【i】【j】+(n-i)* x * (t + z * j)(后 n-i 个放红塔)+ (n-i)*(i - j) y *(t+j * z))(前面绿塔对后面的伤害)

注意考虑全部红塔的情况


代码:

#include <cstdio>#include <cstring>#include <string>#include <queue>#include <stack>#include <map>#include <vector>#include <iostream>#include <algorithm>#include <cmath>#include <set>#include <utility>#define Del(a,b) memset(a,b,sizeof(a))const long long N = 1600;using namespace std;long long dp[N][N];int main(){    long long T;    scanf("%I64d",&T);    for(long long cas=1;cas<=T;cas++)    {        long long n,x,y,z,t;        scanf("%I64d%I64d%I64d%I64d%I64d",&n,&x,&y,&z,&t);        memset(dp,0,sizeof(dp));        long long ans = n * x * t;        for(long long i=1;i<=n;i++)        {            for(long long j=0;j<=i;j++)            {                dp[i][j]=max(dp[i][j],dp[i-1][j]+(i-j-1)*y*(t+j*z));                if(j!=0)                    dp[i][j]=max(dp[i][j],dp[i-1][j-1]+(i-j)*y*(t+(j-1)*z));                ans=max(ans,dp[i][j]+(n-i)*(x+(i-j)*y)*(t+j*z));            }        }        printf("Case #%I64d: %I64d\n",cas,ans);    }    return 0;}


0 0
原创粉丝点击