/*
思考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;
}
小飞打地鼠
于 2025-01-21 14:48:21 首次发布