题目链接
题解:dp,dp[i][j]表示左边取i个,右边取j个,最大值为dp[i][j],状态转移方程为:dp[i][j]=max(dp[i-1][j]+(i+j)*a[i],dp[i][j-1]+(i+j)*a[n-j+1])
下面是AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define int long long
using namespace std;
int a[2020];
int dp[2020][2020];//dp[i][j]表示左边选择了i个右边选择了j个
int prefix[2020];
int suffix[2020];
signed main()
{
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
dp[0][0]=0;
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
{
if(i+j>n) continue;
if(i==0&&j==0) continue;
if(i==0&&j!=0) dp[i][j]=dp[i][j-1]+j*a[n-j+1];
if(i!=0&&j==0) dp[i][j]=dp[i-1][j]+i*a[i];
if(i!=0&&j!=0) dp[i][j]=max(dp[i-1][j]+(i+j)*a[i],dp[i][j-1]+(i+j)*a[n-j+1]);
}
}
int maxx=-1;
for(int i=0;i<=n;i++)
{
maxx=max(maxx,dp[i][n-i]);
}
cout<<maxx<<endl;
}
总结:此题中有两种限制条件,一个是从左边拿,一个是从右边拿,两位dp即可。