题意
n个数在一个双端队列中,每次从队首或队尾出。出的第n个数乘以n,最后加起来,求最大和。
思路
第一次区间dp
dp[i][j] 代表从i取到j的最大总数
dp[i][j] = max(dp[i+1][j]+a[i](n+i-j) , dp[i][j-1]+a[j](n+i-j));
代码
#include <algorithm>
#include <cstdio>
#include <iostream>
#define N 2200
#define INF 0x7f7f7f7f
using namespace std;
int val[ N ];
int dp[ N ][ N ];
int main () {
int n;
while ( ~scanf ( "%d", &n ) ) {
for ( int i = 0; i < n; ++i ) {
scanf ( "%d", &val[ i ] );
//从最后一个 ( 第n天 )往前取,直到取完所有
// dp[ i ][ i ] = val[ i ] * n;
}
//从区间长度为1开始一直到n
for ( int len = 0; len < n; ++len )
//从i开始
for ( int i = 0; i + len < n; ++i ) {
int l = i, r = i + len;
dp[ l ][ r ] = max ( dp[ l + 1 ][ r ] + val[ l ] * ( n + l - r ),
dp[ l ][ r - 1 ] + val[ r ] * ( n + l - r ) );
}
printf ( "%d\n", dp[ 0 ][ n - 1 ] );
}
return 0;
}