题目描述 Description
塔防游戏(Tower Defence)是dd_engi非常喜爱的一类休闲游戏。在这类游戏中,玩家需要在地图上摆放各种防御单位,打击并阻止试图跨越地图的敌对单位。一般而言,敌对单位不会攻击防御单位,但若敌对单位未被防御单位消灭且成功跨越地图,玩家的生命数会减少。
dd_engi设计出了一种一维的塔防游戏,并将其命名为“魔法塔防”,规则如下:
游戏的地图是一行NNN个连续的魔法塔,其中行的一端是入口,另一端是出口,怪兽会从地图的一端向另一端移动。初始时,怪兽通过每个魔法塔的时间是TTT秒。玩家可以在这NNN个魔法塔中放置魔法师以对经过的怪兽造成伤害,每个魔法塔中最多放置一个魔法师,且放置好的魔法师不能改变位置。
共有三种不同属性的魔法师,分别是红色魔法师、蓝色魔法师和绿色魔法师,作用分别是攻击、减速以及下毒。当怪兽经过一个红色魔法师所在的魔法塔时,每秒钟生命值会减少RRR点;当怪兽从一个蓝色魔法师所在的魔法塔走出之后,通过每个魔法塔的时间延长BBB秒;当怪兽从一个绿色魔法师所在的魔法塔走出之后,每秒钟会因中毒失去GGG点生命值。蓝色魔法师的减速效果和绿色魔法师的下毒效果是可以累加的。也就是说,怪兽通过nnn个蓝色魔法师所在的魔法塔之后,它通过每个魔法塔的时间会变成T+BT+BT+B×nnn秒;怪兽通过nnn个绿色魔法师所在的魔法塔之后,它每秒钟会因中毒失去GGG×nnn点生命值。
现在,你的任务是,在这NNN个魔法塔里放置各种类型的魔法师,使通过的怪兽失去的生命值最大。输出这个最大值。
输入 Input
一行,五个空格隔开的整数 N、R、G、B、TN、R、G、B、TN、R、G、B、T。
输出 Output
只需输出一行一个整数,即通过的怪兽失去的最大的生命值。
样例输入 Sample Input
5 4 3 2 1
样例输出 Sample Output
82
限制 Limits
数据范围
20%20\%20%的数据满足 N≤12N≤12N≤12。
50%50\%50%的数据满足 N≤100N≤100N≤100。
100%100\%100%的数据满足1≤N≤1024;0≤R,G,B≤65536;0≤T≤31≤N≤1024; 0 ≤ R, G, B ≤65536; 0 ≤ T ≤ 31≤N≤1024;0≤R,G,B≤65536;0≤T≤3。
Time Limit : 1s1s1s & Memory Limit : 128MB128MB128MB
看题,还是没思路
要维护三个状态的话,n3n^3n3继续超时
要维护两个的话,维护哪两个?
随便两个?肯定不行,准确性呢?
于是爆零…
首先做这道题得会玩塔防游戏(据说我只玩的PvZ是塔防?)
蓝法师(就是冰法师)和绿法师(毒法师)是加Buff的(自带延长效果,类比寒冰射手,只是僵尸再也不会回原来状态了),绝对要放到前面(为啥?孩子不要沉迷于学习…),红法师(火法师)放在最后(gank掉剩下的血)。
ang?这不是贪心吗…
贪心优化的DP…
既然是要冰法师和毒法师放前面,维护的两个状态就是这两个,火法师做差求出
代码应该还很好懂吧…
#include <cstdio>
#define MAXN 1025
using 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,你得先打好游戏…