[DP] [贪心] [Vijos P1417] 魔法塔防 (mtower)

来源:互联网 发布:河南千百知有限公司 编辑:程序博客网 时间:2024/06/09 23:49

题目描述 Description

塔防游戏(Tower Defence)是dd_engi非常喜爱的一类休闲游戏。在这类游戏中,玩家需要在地图上摆放各种防御单位,打击并阻止试图跨越地图的敌对单位。一般而言,敌对单位不会攻击防御单位,但若敌对单位未被防御单位消灭且成功跨越地图,玩家的生命数会减少。
dd_engi设计出了一种一维的塔防游戏,并将其命名为“魔法塔防”,规则如下:
游戏的地图是一行N个连续的魔法塔,其中行的一端是入口,另一端是出口,怪兽会从地图的一端向另一端移动。初始时,怪兽通过每个魔法塔的时间是T秒。玩家可以在这N个魔法塔中放置魔法师以对经过的怪兽造成伤害,每个魔法塔中最多放置一个魔法师,且放置好的魔法师不能改变位置。
共有三种不同属性的魔法师,分别是红色魔法师、蓝色魔法师和绿色魔法师,作用分别是攻击、减速以及下毒。当怪兽经过一个红色魔法师所在的魔法塔时,每秒钟生命值会减少R点;当怪兽从一个蓝色魔法师所在的魔法塔走出之后,通过每个魔法塔的时间延长B秒;当怪兽从一个绿色魔法师所在的魔法塔走出之后,每秒钟会因中毒失去G点生命值。蓝色魔法师的减速效果和绿色魔法师的下毒效果是可以累加的。也就是说,怪兽通过n个蓝色魔法师所在的魔法塔之后,它通过每个魔法塔的时间会变成T+B×n秒;怪兽通过n个绿色魔法师所在的魔法塔之后,它每秒钟会因中毒失去G×n点生命值。
现在,你的任务是,在这N个魔法塔里放置各种类型的魔法师,使通过的怪兽失去的生命值最大。输出这个最大值。

输入 Input

一行,五个空格隔开的整数 NRGBT

输出 Output

只需输出一行一个整数,即通过的怪兽失去的最大的生命值。

样例输入 Sample Input

5 4 3 2 1

样例输出 Sample Output

82

限制 Limits

数据范围
20%的数据满足 N12
50%的数据满足 N100
100%的数据满足1N1024;0R,G,B65536;0T3
Time Limit : 1s & Memory Limit : 128MB

看题,还是没思路
要维护三个状态的话,n3继续超时
要维护两个的话,维护哪两个?
随便两个?肯定不行,准确性呢?
于是爆零……
首先做这道题得会玩塔防游戏(据说我只玩的PvZ是塔防?)
蓝法师(就是冰法师)和绿法师(毒法师)是加Buff的(自带延长效果,类比寒冰射手,只是僵尸再也不会回原来状态了),绝对要放到前面(为啥?孩子不要沉迷于学习……),红法师(火法师)放在最后(gank掉剩下的血)。
ang?这不是贪心吗……
贪心优化的DP……
既然是要冰法师和毒法师放前面,维护的两个状态就是这两个,火法师做差求出
代码应该还很好懂吧……

#include <cstdio>#define MAXN 1025using namespace std;long long dp[MAXN][MAXN];long long ans;long long n,r,g,b,t;long long mymax(long long a,long long b){    return a>b?a:b;}int main(){    scanf("%lld %lld %lld %lld %lld",&n,&r,&g,&b,&t);    for (int i=0;i<=n;i++) //i为总共放置蓝法师塔数        for (int j=0;j<=n-i;j++) //j为总共放置绿法师塔数        {            if (i) //你得先有蓝法师                dp[i][j]=mymax(dp[i][j],dp[i-1][j]+g*j*(t+b*(i-1))); //只有走出塔才生效,i或j需要减1            if (j) //同理                dp[i][j]=mymax(dp[i][j],dp[i][j-1]+g*(j-1)*(t+b*i));            ans=mymax(ans,dp[i][j]+(n-i-j)*(g*j+r)*(t+i*b));//小小的运用了一下结合律        }    printf("%lld\n",ans);    return 0;}

学好OI,你得先打好游戏……

0 0