题意:给你一个序列,每次只能从头或为取数,然后乘以这是第几个数,最后加和,是加和最大
思路:假设长度最开始是1,然后依次枚举长度,以及起点,dp[i][j]是又里面的两端点扩出来的(ps:代码不是这么写的)
代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=2007; int a[maxn],dp[maxn][maxn]; int main() { int n; while(~scanf("%d",&n)){ for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } memset(dp,0,sizeof(dp)); for(int i=1;i<=n;i++){ dp[i][i]=a[i]; } for(int i=n;i>=1;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; }