HNU-LTS buy wine(区间DP)

在一个阳光明媚的下午,ltslts的朋友来看他。所以他决定买些酒。

 

我们知道店里所有的酒都在同一个架子上,这些酒从左到右编号是1到n。

 

他们的朋友很有钱,所以他们会买所有的酒。但他的饮酒能力有限,所以他每天只买一瓶酒。

 

我们都知道,酒越久越值钱。

 

第一种情况下,第i瓶葡萄酒的价值为vi。在第t天,ltslts将在货架最左边或最右边购买一瓶葡萄酒,并得到值vi⋅t。

 

很明显,所有的酒都会在第n天被ltslts买走,他想知道他能得到的最大价值是多少。

 

例如,我们考虑n=5,葡萄酒的价值是{1,3,1,5,2}。

 

第一天,我们买了最左边的酒,得到了1个价值点,剩下的酒是{3,1,5,2}。

第二天,我们买了最右边的酒,得到了4个值点,剩下的酒是{3,1,5}。

第三天,我们买了最左边的酒,得到了9个价值点,剩下的酒是{1,5}。

第四天,我们买了最左边的酒,得到了4个价值点,剩下的酒是{5}。

最后一天,我们得到了25个价值点,我们总共得到了43个价值点。

输入

第一行包含单个整数n(1≤n≤2000),表示葡萄酒的数量。

 

在接下来的n行中,每行包含一个整数vi(1≤vi≤109),表示第i种葡萄酒的价值。

 

输出

在一行中打印单个整数:ltslts可以获得的最大值。

/*
 *author: zlc
 *zucc_acm_lab
 *just do it
 */
#include<bits/stdc++.h> 
using namespace std;
typedef long long ll;
const double pi=acos(-1.0);
const double eps=1e-6;
const int mod=1e9+7;
const int inf=1e9;
const int maxn=2e5+100;
inline ll read () {ll x=0;ll f=1;char ch=getchar();while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}return x*f;}
ll qpow (ll a,ll b) {ll res=1;a%=mod; assert(b>=0); for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
int n;
ll a[maxn];
ll c[maxn];
ll ans=0;
// 1 3 1 5 2
// 1+2*2+3*3+1*4+5*5
//dp[l][r]表示取到左下标为l,右下标为r的最大值
deque<int> q;
ll dp[5005][5005];
int main () {
    n=read();
    for (int i=1;i<=n;i++) a[i]=read();
    ll tot=1;
    int l=1,r=n;
    for (int i=1;i<=n;i++) {
        for (int j=1;j<=n;j++) {
            dp[j][j+i-1]=max(dp[j+1][j+i-1]+a[j]*(n-i+1),dp[j][j+i-2]+a[j+i-1]*(n-i+1));
        }
    } 
    ans=dp[1][n];
    printf("%lld\n",ans);
} 

 

posted @ 2020-09-16 23:00  zlc0405  阅读(143)  评论(0编辑  收藏  举报