传送门
每次从区间的左端点选择或者从右端点进行选择
逆着就是从中间进行向两边进行扩展。
因为左区间是向左边扩展,右区间是向右区间扩展,二维遍历一下左右区间,左区间是从[n,1],右区间是[i+1,n]
因为当前区间是[i,j],表示已经进行了j - i次,当前是n - (j - i)次操作
状态转移方程dp[i][j] = max(dp[i + 1][j] + (n - j + i) * a[i], dp[i][j - 1] + a[j] * (n - j + i));
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N = 2005;
int a[N];
int dp[N][N];
int main(){
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = 1; i <= n; i++) dp[i][i] = a[i] * n;
for(int i = n - 1; i >= 1; i--) {
for(int j = i + 1; j <= n; j++) {
dp[i][j] = max(dp[i + 1][j] + a[i] * (n + i - j), dp[i][j - 1] + a[j] * (n + i - j));
}
}
printf("%d
", dp[1][n]);
return 0;
}