【题目链接】
http://poj.org/problem?id=3186
一个长度为n的数列,每次都可以从两端取一个值,每次获得的权值等于数列值乘取的次数。问全部取完最大权值。
dp[i][j]表示从i到j最大的权值,这样正的没办法计算第几次取的,所以只能从中间往两边扩,也就是从最后一次取往前推。注意循环i要倒着,不知道为什么要倒着想想01背包。
#include
#include
#include
#include
#include
using namespace std;
#define LL long long
#define inf 0x3f3f3f3
const int N = 2e3+5;
//从中间往两边扩,第几次选择为n-(j-i);
int dp[N][N]; //表示 从i到j中最大值
int a[N];
int main()
{
int n;
while (~scanf("%d",&n)){
for (int i = 1; i <= n; i++)scanf("%d",&a[i]);
for (int i = n; i > 0; i--)
for (int j = i; 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\n",dp[1][n]);
}
return 0;
}