poj 3168 Treats for the Cows 區間dp

題意:給出的一系列的數字,可以看成一個雙向隊列,每次只能從隊首或者隊尾出隊,第i個出隊就拿這個數乘以i,最後將和加起來,求最大和

由裏向外推,dp[i][j],表示從隊首取了前i個,從隊尾取了後j個,枚舉i,j

狀態轉移方程dp[i][j]=max(dp[i-1][j]+v[i]*(i+j),d[i][j-1]+v[n-j+1]*(i+j));

#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
const int N=3001;
int dp[N][N];
int n,v[N];
int MAX(int x,int y)
{
    if(x>y)
    return x;
    return y;
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&v[i]);
            dp[i][i]=n*v[i];
        }
        for(int len=2;len<=n;len++)
        {
            for(int i=1;i<=n-len+1;i++)
            {
                int j=i+len-1;
                if(i+1<=j&&i+1<=n)
                {
                    dp[i][j]=MAX(dp[i][j],dp[i+1][j]+(n-j+i)*v[i]);
                }
                if(j-1>=i)
                {
                    dp[i][j]=MAX(dp[i][j],dp[i][j-1]+(n-j+i)*v[j]);
                }
            }
        }
        printf("%d\n",dp[1][n]);
    }
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章