本来想做一道网络流的,结果Tyvj把这个水题扔到了网络流的分类里面,就顺手做了==
背景
广东汕头聿怀初中 Train#2 Problem2
描述
给出长度为N的数列{A_i},每次可以从最左边或者最右边取走一个数,第i次取数得到的价值是i * A_j。求价值之和最大的取数方案。
输入格式
第一行,一个整数,表示数列长度N。
接下来N行,每行一个整数,表示数列A_i。
输出格式
一个整数,表示最大的价值之和。
测试样例1
输入
5
1
3
1
5
2
输出
43
数据范围
N <= 2000 , A_i <= 1000
题解
dp[i][k]表示正准备第k次取数,正着数已经取到第i-1个数时的最大值,其实可以把k也给省掉的==不过懒得改了
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define maxn 2020
using namespace std;
long long dp[maxn][maxn];
long long ans;
long long a[maxn];
int n;
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]);
memset(dp, 0, sizeof(dp));
for(int k = 2; k <= n; k++)
for(int i = 1; i <= k; i++)
dp[i][k] = max(dp[i][k-1] + (k-1)*a[n-k+i+1], dp[i-1][k-1] + (k-1)*a[i-1]);
for(int i = 1; i <= n; i++)
ans = max(ans, dp[i][n] + n*a[i]);
printf("%d\n", ans);
}