本题在洛谷上的链接:https://www.luogu.org/problemnew/show/P2858
算是一道区间DP的水题,很容易设计出状态dp[i][j]表示[i,j]所能产生的最大价值,那么有dp[i][j]=max(dp[i+1][j]+v[i]*(n-l+1),dp[i][j-1]+v[j]*(n-l+1));
注意,这里相当于将元素添加到序列中,因此最先加入的反而是出售较晚的,同时,不难得出初始边界,dp[i][i]=n*v[i]。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <algorithm> 3 4 using namespace std; 5 6 const int maxn = 2005; 7 8 int v[maxn], dp[maxn][maxn]; 9 10 int main() { 11 int n; 12 scanf("%d", &n); 13 for (int i = 1; i <= n; ++i) 14 scanf("%d", &v[i]); 15 for (int i = 1; i <= n; ++i) 16 dp[i][i] = v[i] * n; 17 for (int l = 2; l <= n; ++l) 18 for (int i = 1; i <= n - l + 1; ++i) { 19 int j = i + l - 1; 20 dp[i][j] = max(dp[i + 1][j] + v[i] * (n - l + 1), dp[i][j - 1] + v[j] * (n - l + 1)); 21 } 22 printf("%d", dp[1][n]); 23 return 0; 24 }