植物大战僵尸!
时间限制:10000 MS,空间限制:3000 KB,评测说明 : 时限1000ms
问题描述
何老板喜欢玩植物大战僵尸,在游戏里有一条水平道路,道路的一端是入口,另一端是房子。僵尸会从道路的入口一端向房子一端移动。这条道路刚好穿过N块连续的空地。初始时,僵尸通过每块空地的时间是T秒。玩家可以在这N个空地中种植植物以攻击经过的僵尸,每块空地中只能种植一种植物。
共有三种不同类型的植物,分别是红草、蓝草和绿草,作用分别是攻击、减速以及下毒。每种植物只能在僵尸通过它所在空地的这段时间内攻击到僵尸。
当僵尸经过一块红草所在的空地时,每秒钟生命值会减少R点;当僵尸从一块蓝草所在的空地走出之后,通过每块空地的时间延长B秒;当僵尸从一块绿草所在的空地走出之后,每秒钟会因中毒减少G点生命值。蓝草的减速效果和绿草的下毒效果是可以累加的。也就是说,僵尸通过n块蓝草所在的空地之后,它通过每块空地的时间会变成T+B*n秒;僵尸通过n块绿草所在的空地之后,它每秒钟会因中毒失去G*n点生命值。注:减速和中毒效果会一直持续下去
何老板想知道:怎样在这N块空地里种植各种类型的植物,才能使通过的僵尸失去的生命值最大。输出这个最大值。
输入格式
一行,五个空格隔开的整数N、R、G、B、T
输出格式
一行,一个整数,即通过的僵尸失去的最大的生命值
样例输入
5 4 3 2 1
样例输出
82
提示
30%的数据满足N<=100。
50%的数据满足N<=1000。
100%的数据满足1<=N<=2000; 0 <= R, G, B <= 65536; 0 <= T <= 3。
题解:
状态:f[x][y]:有x绿,y蓝能造成的最大伤害值
决策:x+y位置放蓝还是绿
方程:f[x][y]=max{f[x][y-1]+(t+(y-1)*b)*(x*g);f[x+1][y]+(t+y*b)*(x-1)*g;}
总共伤害:g[x][y]=f[x][y]+(n-x-y)*(t+y*b)*(r+g*x);
然而空间超了于是我们考虑一下空间优化,这里引入滚动数组!
什么是滚动数组 https://blog.youkuaiyun.com/baijiuhao/article/details/87779326
对于这道题滚动数组的使用还有些地方需要注意,注意事项在代码里面,下面是代码部分:
#include<bits/stdc++.h>//感谢nonstop大佬!
using namespace std;
long long f[2][2000+5],ans;
int main()
{
long long n,r,g,b,t;
scanf("%lld%lld%lld%lld%lld",&n,&r,&g,&b,&t);
for (int x=0;x<=n;x++)
for (int y=0;y<=n-x;y++)
{
f[x&1][y]=0;//释放空间,防止因为之前的数据而出现错误
if (y!=0) f[x&1][y]=f[x&1][y-1]+(t+b*x)*g*(y-1);
if (x!=0) f[x&1][y]=max(f[x&1][y],f[(x-1)&1][y]+(t+b*(x-1))*g*y);
ans=max(ans,f[x&1][y]+(n-x-y)*(t+b*x)*(r+y*g));//要及时更新,不然就会排除掉之前的正确答案
}
printf("%lld",ans);
return 0;
}