【POJ - 3186】Treats for the Cows (區間dp)

Treats for the Cowsios

先搬中文spa

Descriptions:.net

給你n個數字v(1),v(2),...,v(n-1),v(n),每次你能夠取出最左端的數字或者取出最右端的數字,一共取n次取完。假設你第i次取的數字是x,你能夠得到i*x的價值。你須要規劃取數順序,使得到的總價值之和最大。code

Inputblog

第一行一個數字n(1<=n<=2000)。ip

下面n行每行一個數字v(i)。(1<=v(i)<=1000)ci

Outputget

輸出一個數字,表示最大總價值和。string

Sample Inputit

5

1

3

1

5

2

Sample Output

43

Hint

按照這種下標順序取數: 1, 5, 2, 3, 4

取出的數按順序爲:1, 2, 3, 1, 5

最大總價值和:1x1 + 2x2 + 3x3 + 4x1 + 5x5 = 43.

題目連接:
https://vjudge.net/problem/POJ-3186

 

區間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))  即取右邊的數   取左邊的數  比較哪一個大

 

AC代碼

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define Mod 1000000007
#define eps 1e-6
#define ll long long
#define INF 0x3f3f3f3f
#define MEM(x, y) memset(x, y, sizeof(x))
#define Maxn 2000+10
using namespace std;
int n;
int dp[Maxn][Maxn],a[Maxn];
int main()
{
    MEM(dp,0);
    MEM(a,0);
    cin>>n;
    for(int i=0;i<n;i++)
        cin>>a[i];
    for(int len=0;len<n;len++)//區間長度len
    {
        for(int i=0;i+len<n;i++)//固定區間左邊起點
        {
            int l=i,r=i+len;//區間左、右點
            //取右邊的數   取左邊的數  比較哪一個大
            dp[l][r]=max(dp[l+1][r]+a[l]*(n+l-r),dp[l][r-1]+a[r]*(n+l-r));
        }
    }
    cout<<dp[0][n-1]<<endl;
    return 0;

}

 

 

 

 

給你n個數字v(1),v(2),...,v(n-1),v(n),每次你能夠取出最左端的數字或者取出最右端的數字,一共取n次取完。假設你第i次取的數字是x,你能夠得到i*x的價值。你須要規劃取數順序,使得到的總價值之和最大。Input第一行一個數字n(1<=n<=2000)。
下面n行每行一個數字v(i)。(1<=v(i)<=1000)Output輸出一個數字,表示最大總價值和。Sample Input

5
1
3
1
5
2

Sample Output

43

Hint按照這種下標順序取數: 1, 5, 2, 3, 4取出的數按順序爲:1, 2, 3, 1, 5最大總價值和:1x1 + 2x2 + 3x3 + 4x1 + 5x5 = 43.

相關文章
相關標籤/搜索