植物大战僵尸

Description

   何老板喜欢玩植物大战僵尸,在游戏里有一条水平道路,道路的一端是入口,另一端是房子。僵尸会从道路的入口一端向房子一端移动。这条道路刚好穿过N块连续的空地。初始时,僵尸通过每块空地的时间是T秒。玩家可以在这N个空地中种植植物以攻击经过的僵尸,每块空地中只能种植一种植物。 
   共有三种不同类型的植物,分别是红草、蓝草和绿草,作用分别是攻击、减速以及下毒。每种植物只能在僵尸通过它所在空地的这段时间内攻击到僵尸。 
   当僵尸经过一块红草所在的空地时,每秒钟生命值会减少R点;当僵尸从一块蓝草所在的空地走出之后,通过每块空地的时间延长B秒;当僵尸从一块绿草所在的空地走出之后,每秒钟会因中毒减少G点生命值。蓝草的减速效果和绿草的下毒效果是可以累加的。也就是说,僵尸通过n块蓝草所在的空地之后,它通过每块空地的时间会变成T+B*n秒;僵尸通过n块绿草所在的空地之后,它每秒钟会因中毒失去G*n点生命值。注:减速和中毒效果会一直持续下去 
何老板想知道:怎样在这N块空地里种植各种类型的植物,才能使通过的僵尸失去的生命值最大。输出这个最大值。

Input

一行,五个空格隔开的整数N、R、G、B、T

Output

一行,一个整数,即通过的僵尸失去的最大的生命值

Sample Input

5 4 3 2 1

Sample Output

82

Hint

20%的数据满足N<=12。 
50%的数据满足N<=100。 
100%的数据满足1<=N<=1024; 0 <= R, G, B <= 65536; 0 <= T <= 3。


【分析】

        第一反应都应该是动规吧。但是却有点无从下手的感觉,仔细分析后发现,红色的草一定是放在最后的。得到了这个结论,那么我们这样定义状态数组:F[i][j]表示前i+j个格子中,绿草(毒)种了i颗,蓝草(减速)种了j颗时前i+j格的伤害

       既然红草是放在最后的,那么可以最后来计算他的伤害。

       我们很容易便得到了状态转移方程:F[i][j]=max{F[i-1][j]+(i-1)*G*(T+B*j),

                                                                                          F[i][j-1]+i*G*(T+B(j-1))}; (即加上前面的状态对于当前格子的伤害)

        然后对于每个F[i][j],它的在余下的(N-i-j)格的伤害定义为g[i][j]=(N-i-j)*(T+B*j)*(R+G*i)

        那么最后的答案ans=max{F[i][j]+g[i][j]};


【代码】

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<ctime>
#include<iostream>
#include<algorithm>
using namespace std;
long long N,R,G,B,T,f[1050][1050];
void _init()
{
	scanf("%I64d%I64d%I64d%I64d%I64d",&N,&R,&G,&B,&T);
}
void _solve()
{
	for(int i=0;i<=N;i++)
	    for(int j=0;j+i<=N;j++)
	    {
	    	if(i-1>=0)
	            f[i][j]=max(f[i-1][j]+(i-1)*G*(T+B*j),f[i][j]);
	        if(j-1>=0)
	            f[i][j]=max(f[i][j],f[i][j-1]+i*G*(T+B*(j-1)));
	    }
	long long ans=0;
	for(int i=0;i<=N;i++)
	    for(int j=0;j+i<=N;j++)
	    {
	    	int k=N-i-j;
	    	ans=max(ans,f[i][j]+k*(T+B*j)*(R+G*i));
	    }
	printf("%I64d\n",ans);
}
int main()
{
	_init();
	_solve();
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值