题目链接:http://poj.org/problem?id=3186
题意:给一行n个数,每次可以取出行首或者行末的数,如果第ai是第i次取出的,可以得到ai*i的收益,求最大的总收益;
思路:区间dp
我们可以用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))
注意一下边界情况就ok啦。。。
代码:
1 #include <iostream>
2 #define MAXN 2010
3 using namespace std;
4
5 int a[MAXN], dp[MAXN][MAXN];
6
7 int main(void){
8 ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
9 int n, num=0;
10 cin >> n;
11 for(int i=1; i<=n; i++){
12 cin >> a[i];
13 }
14 for(int i=0; i<=n; i++){
15 for(int j=0; j+i<=n; j++){
16 if(j>0&&i>0){
17 dp[i][j]=max(dp[i-1][j]+a[i]*(i+j), dp[i][j-1]+a[n-j+1]*(i+j));
18 }else if(i>0){
19 dp[i][j]=dp[i-1][j]+a[i]*i;
20 }else if(j>0){
21 dp[i][j]=dp[i][j-1]+a[n-j+1]*j;
22 }
23 num=max(num, dp[i][j]);
24 }
25 }
26 cout << num << endl;
27 return 0;
28 }