题解
题目难度:中等
知识点:动态规划、数组
解题思路:首先一看这种根据选择来取最大最小值的题,就应该想到可以使用动态规划进行解题,将整个大问题划分为小问题进行解决。难点主要在考虑怎么将大问题划分为小问题。然后,因为整个可选项是组成"环"的数据形式,所以在选择过程中,使用求余的方式来进行数据采取。
整个解题步骤:
第一步:因为使用动态规划进行解题,所以可以构建一个二维数组来保存数据。
第二步:这一步是对问题进行一个划分,因为只能选择首尾,所以只存在两种选项,我们需要对这个"选择"进行描述。因为这边求的是一个差,所以可以直接用二维数组保存这个差值。
dp[j][(k+j)%n] = max(-1dp[(j+1)%n][(k+j)%n]+num[j], -1dp[j][(k+j-1)%n]+num[(k+j)%n])
第三步:直接对这个二维数组进行数据比较,取最大值即可。
| 规划 | 0 | 1 | 2 | 3 | 4 |
|---|---|---|---|---|---|
| 0 | 第1个值 | 最小差值 | |||
| 1 | 第2个值 | 最小差值 | |||
| 2 | 第3个值 | 最小差值 | |||
| 3 | 第4个值 | 最小差值 | |||
| 4 | 最小差值 | 第5个值 |
#include<iostream>
#include<cstring>
using namespace std;
#define max(a,b) (a>b?a:b)
int main(){
int n;
cin >> n;
int dp[n+1][n+1];
int num[n];
for(int i=0; i<n; ++i)
cin >> num[i];
int result = 0;
memset(dp,0, sizeof(dp));
for(int k=0; k<n; k++)
dp[k][k] = num[k];
for(int k=1; k<n; k++) {
for(int j=0; j<n; j++) {
dp[j][(k+j)%n] = max(-1*dp[(j+1)%n][(k+j)%n]+num[j], -1*dp[j][(k+j-1)%n]+num[(k+j)%n]);
}
}
for(int i=0; i<n; ++i)
result = max(dp[i][(i+n-1)%n], result);
cout << result << endl;
return 0;
}
京公网安备 11010502036488号