hdu 4939 Stupid Tower Defense 2014多校七 DP

题目链接:hdu 4939

        一个塔防游戏:给定一条长度为n的直线,要在每一个格点都造塔,小怪每走一个格点需要t秒钟,现在提供给你三种塔:(1)非常耿直的红色塔,仅仅当怪物经过该点时造成每秒x点伤害;(2)带诅咒的绿塔,经过该点时不造成伤害,经过之后直到走完全程造成每秒y点伤害(伤害可叠加);(3)塔防中肯定有的减速蓝塔,经过时没有效果,经过之后怪物每走一个格点都需要额外的z秒(减速效果同样可叠加)。问现在造塔能怪物走完全程最大能造成多少伤害。

        红色塔太耿直,只有一次作用,而且绿蓝塔对当前经过的怪物没有实际作用,所以在最后一个格点放置的一定是红塔。蓝绿塔的后效足,所以优先放在前面。而它们对于之后点的影响仅仅与他们的数量有关,而与他们的排列顺序无关。(如对第5个格点,之前已经有两个绿塔,两个蓝塔,无论它们的顺序如何,在该点的造成的伤害都是2*y*(t+2z))

        因此,我们记录状态dp[i][j]表示对于前i+j个格点有i个绿塔,j个蓝塔在前i+j个格点造成的总的伤害的最大值

        状态转移方程:dp[i][j]=max(dp[i-1][j]+(i-1)*y*(t+j*z)+dp[i][j-1]+i*y*(t+(j-1)*z))

/******************************************************
 * File Name:   1005.cpp
 * Author:      kojimai
 * Creater Time:2014年08月12日 星期二 13时43分47秒
******************************************************/

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
long long dp[1505][1505];//i-green j-blue
int main()
{
	int keng,Case=1;
	long long n,x,y,z,t;
	scanf("%d",&keng);
	while(keng--)
	{
		cin>>n>>x>>y>>z>>t;
		long long ans=x*t*n;
		memset(dp,0,sizeof(dp));
		for(long long i=1;i<=n;i++)
		{
			for(long long j=0;j<=i;j++)
			{
				dp[j][i-j]=0;
				if(j)
					dp[j][i-j]=max(dp[j][i-j],dp[j-1][i-j]+y*(j-1)*(t+(i-j)*z));
				if(i-j)
					dp[j][i-j]=max(dp[j][i-j],dp[j][i-1-j]+y*(j)*(t+(i-j-1)*z));
				//cout<<j<<' '<<i-j<<' '<<dp[j][i-j]<<endl;
				ans=max(ans,dp[j][i-j]+(n-i)*(x*(t+z*(i-j))+y*j*(t+(i-j)*z)));//假设之后的全部都是红塔
			}
		}
		printf("Case #%d: ",Case++);
		cout<<ans<<endl;
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值