poj 3186 Treats for the Cows (区间dp)

【题目链接】
http://poj.org/problem?id=3186

题目意思

一个长度为n的数列,每次都可以从两端取一个值,每次获得的权值等于数列值乘取的次数。问全部取完最大权值。

解题思路

dp[i][j]表示从i到j最大的权值,这样正的没办法计算第几次取的,所以只能从中间往两边扩,也就是从最后一次取往前推。注意循环i要倒着,不知道为什么要倒着想想01背包。

代码部分

#include 
#include 
#include 
#include 
#include 
using namespace std;
#define LL long long
#define inf 0x3f3f3f3
const int N = 2e3+5;
//从中间往两边扩,第几次选择为n-(j-i); 
int dp[N][N];   //表示 从i到j中最大值 
int a[N];
int main()
{
    int n;
    while (~scanf("%d",&n)){
        for (int i = 1; i <= n; i++)scanf("%d",&a[i]);
        for (int i = n; i > 0; 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;
}

你可能感兴趣的:(动态规划)