poj3186(区间dp)

题目链接: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 }

 

posted @ 2017-01-23 00:04  geloutingyu  阅读(808)  评论(0编辑  收藏  举报