洛谷P2858 [USACO06FEB] Treats for the Cows G/S 题解

本题做法

  • 区间 DP。

思路

这题我们可以用区间 DP 来求解。令 \(dp[i][j]\) 表示第 \(i\) 个零食到第 \(j\) 个零食所可以得到的最大价值,那么由于 \(dp[i][j]\) 可以由 \(dp[i+1][j]\)\(dp[i][j-1]\) 转移而来(可以自己思考一下为什么是这 2 个),所以很容易得到状态转移方程:

\[dp[i][j]=\max\{dp[i+1][j]+v[i]\times a,dp[i][j-1]+v[j]\times a\} \]

其中 \(a=n-len+1\)\(len\) 为区间长度,即 \(j-i+1\))。

最后的答案就是 \(dp[1][n]\) 了。

代码

#include<bits/stdc++.h>

using namespace std;

typedef long long          ll;
typedef unsigned long long ull;

const int N=2005;

ll n,v[N],dp[N][N];

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>v[i];
    for(int i=1;i<=n;i++) dp[i][i]=v[i]*n;
    for(int len=2;len<=n;len++){
        for(int i=1;i+len-1<=n;i++){
            int j=i+len-1,a=n-len+1;
            dp[i][j]=max(dp[i+1][j]+v[i]*a,dp[i][j-1]+v[j]*a);
        }
    }
    cout<<dp[1][n]<<endl;
    return 0;
}
posted @ 2025-08-29 10:32  2789617221guo  阅读(7)  评论(0)    收藏  举报