题解

题目难度:中等

知识点:动态规划、数组

解题思路:首先一看这种根据选择来取最大最小值的题,就应该想到可以使用动态规划进行解题,将整个大问题划分为小问题进行解决。难点主要在考虑怎么将大问题划分为小问题。然后,因为整个可选项是组成"环"的数据形式,所以在选择过程中,使用求余的方式来进行数据采取。
整个解题步骤:
第一步:因为使用动态规划进行解题,所以可以构建一个二维数组来保存数据。
第二步:这一步是对问题进行一个划分,因为只能选择首尾,所以只存在两种选项,我们需要对这个"选择"进行描述。因为这边求的是一个差,所以可以直接用二维数组保存这个差值。
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;
}