小飞打地鼠

/*
思考1:需要认识到方程是从里到外转移
如从[i+1,j]--->[i,j]
此时从i+1来看,移动到i点上次移动的方向相同所以只能获得一半的分数而且获得的是a[i]的
而不是a[i+1]的。至于移动的方向与上次相同,是因为i+1只能从右到左走过来
同理,从j走过来走过的步数为j-i(从j移动到i)获得全部的a[i](方向相同)
思考2:对于dp[i][j][0](区间[i,j]且在i点)为什么不能有关于dp[i][]的?
因为此时考虑的是dp[i][j][0]的上一种情况
现在还没有到达i点,所以从区间[i+1,j]且分别在i+1,j点上讨论
*/
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=510;
int n,a[N];
ll dp[N][N][2];//表示完成的区间是[i,j],0表示在i点,1表示在j点
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			dp[i][j][0]=dp[i][j][1]=-1e18;//初始化
	for(int i=1;i<=n;i++)
		dp[i][i][0]=dp[i][i][1]=a[i];//设置初始条件

	for(int l=2;l<=n;l++)//枚举区间长度 
		for(int i=1;(i+l-1)<=n;i++)//枚举左端点 
		{
			int j=i+l-1;    //区间Dp
      dp[i][j][0]=max(dp[i+1][j][0]+a[i]/2-10,dp[i+1][j][1]+a[i]-10*(j-i));//移动
      dp[i][j][1]=max(dp[i][j-1][0]+a[j]-10*(j-i),dp[i][j-1][1]+a[j]/2-10);
      /*
        思考1:需要认识到方程是从里到外转移
        如从[i+1,j]--->[i,j]
        此时从i+1来看,移动到i点上次移动的方向相同所以只能获得一半的分数而且获得的是a[i]的
        而不是a[i+1]的。至于移动的方向与上次相同,是因为i+1只能从右到左走过来
        同理,从j走过来走过的步数为j-i(从j移动到i)获得全部的a[i](方向相同)
        思考2:对于dp[i][j][0](区间[i,j]且在i点)为什么不能有关于dp[i][]的?
        因为此时考虑的是dp[i][j][0]的上一种情况
        现在还没有到达i点,所以从区间[i+1,j]且分别在i+1,j点上讨论
      */
    }
	printf("%lld\n",max(dp[1][n][0],dp[1][n][1]));
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值