题意:给一行n个数,每次可以取出行首或者行末的数,如果第ai是第i次取出的,可以得到ai*i的收益,求最大的总收益;
我们设dp[i][j],表示从i到j的最大收益。最后输出dp[1][n]即可。
那么对于dp[i][j],我们上一次拿出的肯定是i个或者第j个。
那么dp[i][j]=max( dp[i-1][j]+a[i]*(i+j) , dp[i][j-1]+a[n-j+1]*(i+j)) 注意第二个是n-j+1哦。 因为取尾巴会受到之前的影响的
- #include<stdio.h>
- #include<algorithm>
- using namespace std;
- int dp[2005][2005];
- int v[2005];
- int max(int a,int b)
- {
- if(a>b)
- return a;
- else
- return b;
- }
- int main()
- {
- int i,j,n;
- while(scanf("%d",&n)!=EOF)
- {
- for(i=1;i<=n;i++)
- scanf("%d",&v[i]);
- memset(dp,0,sizeof(dp));
- for(i=0;i<=n;i++)
- for(j=0;i+j<=n;j++)
- {
- if(i==0&&j==0)
- dp[i][j]=0;
- else if(i==0&&j!=0)
- dp[i][j]=max(dp[i][j],dp[i][j-1]+v[n-j+1]*(i+j));
- else if(i!=0&&j==0)
- dp[i][j]=max(dp[i][j],dp[i-1][j]+v[i]*(i+j));
- else
- dp[i][j]=max(dp[i-1][j]+v[i]*(i+j),dp[i][j-1]+v[n-j+1]*(i+j));
- }
- int ans=0;
- for(i=0;i<=n;i++)
- if(dp[i][n-i]>ans)
- ans=dp[i][n-i];
- printf("%d/n",ans);
- }
- return 0;
- }