喵哈哈村的木星传说(三)
发布时间: 2017年4月11日 20:01 最后更新: 2017年4月11日 20:02 时间限制: 1000ms 内存限制: 128M
喵哈哈村有一个挂在空中的木星爷爷,每天晚上都讲一些故事。而星星同学,作为木星爷爷的听众,为了报答,于是每天晚上都会为他解决一个问题。
今天,星星同学要为木星爷爷解决这样一个问题:
给出长度为N的数列a[i],每次可以从最左边或者最右边取走一个数,第i次取数得到的价值是i * a[i]。求价值之和最大的取数方案。
本题包含若干组测试数据。
第一行一个n,表示数列的长度。
第二行n个整数,分别表示数列里的元素a[i]。
满足 1<=n<=2000,0<=a[i]<=1000
输出最多和的答案。
5 1 3 1 5 2
43
C (GCC 4.8) C++ (G++ 4.3) Java (Oracle JDK 1.7)
dp[i][j]:左边用了i个,右边用了j个的最大值,这样状态转移方程便可建立(见代码)
#include<stdio.h>
#include<vector>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
#define maxn 2005
ll a[maxn],dp[maxn][maxn];
int main()
{
ll n,i,j;
while(scanf("%lld",&n)!=EOF)
{
ll ans=0;
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
scanf("%lld",&a[i]);
//dp[0][1]=a[n];
//dp[1][0]=a[1];
for(i=0;i<=n;i++)
{
for(j=0;j<=n-i;j++)
dp[i+1][j+1]=max(dp[i+1][j]+a[n-j+1]*(i+j),dp[i][j+1]+a[i]*(i+j));
}
for(i=0;i<=n;i++)
ans=max(ans,dp[i+1][n-i+1]);
printf("%lld\n",ans);
}
}