洛谷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;
}

浙公网安备 33010602011771号