[区间DP] POJ 3186

来源:互联网 发布:练六级英语听力的软件 编辑:程序博客网 时间:2024/05/22 03:30

题意

n个数在一个双端队列中,每次从队首或队尾出。出的第n个数乘以n,最后加起来,求最大和。

思路

第一次区间dp
dp[i][j] 代表从i取到j的最大总数
dp[i][j] = max(dp[i+1][j]+a[i](n+i-j) , dp[i][j-1]+a[j](n+i-j));

代码

#include <algorithm>#include <cstdio>#include <iostream>#define N 2200#define INF 0x7f7f7f7fusing namespace std;int val[ N ];int dp[ N ][ N ];int main () {    int n;    while ( ~scanf ( "%d", &n ) ) {        for ( int i = 0; i < n; ++i ) {            scanf ( "%d", &val[ i ] );            //从最后一个 ( 第n天 )往前取,直到取完所有            // dp[ i ][ i ] = val[ i ] * n;        }        //从区间长度为1开始一直到n        for ( int len = 0; len < n; ++len )            //从i开始            for ( int i = 0; i + len < n; ++i ) {                int l = i, r = i + len;                dp[ l ][ r ] = max ( dp[ l + 1 ][ r ] + val[ l ] * ( n + l - r ),                                     dp[ l ][ r - 1 ] + val[ r ] * ( n + l - r ) );            }        printf ( "%d\n", dp[ 0 ][ n - 1 ] );    }    return 0;}
原创粉丝点击