分析:
这个题有点像矩阵取数
实际上每次取数的时候,取的区间的答案是不随时间的变化而变化的
也就是说,每一部分的答案都是固定的,
我们可以只看区间(i,j)内的最优答案
反映到实际方案上,我们只要调整一下取数的顺序
按照从两边到中间的区间顺序取数就可以满足题意了
说到底,题目限制只能从两边取的限制是迷惑选手的
那么状态就很简单了
设状态:
f[i][j]表示删掉i到j的所有数能到的最大值
枚举上一次的删除区间端点k
f[i][j]=max{f[i][k]+sum(k+1,j),f[k][j]+sum(i,k-1)
在tyvj上第4个点被卡掉了,原因玄学。。。
这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
using namespace std;
int n,a[110];
int f[110][110];
int abs(int x)
{
if (x>0) return x;
else return -x;
}
int get(int x,int y)
{
if (x==y) return a[x];
if (x>y) swap(x,y);
return abs(a[x]-a[y])*(y-x+1);
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]),f[i][i]=a[i];
for (int i=n-1;i>=1;i--)
for (int j=i+1;j<=n;j++)
for (int k=i;k<=j;k++)
{
if (k!=j) f[i][j]=max(f[i][j],f[i][k]+get(k+1,j));
if (k!=i) f[i][j]=max(f[i][j],f[k][j]+get(i,k-1));
}
printf("%d",f[1][n]);
return 0;
}