AT4533

容易想到区间 dp,

设 $f_{i, j}$ 表示 $i$ 到 $j$ 这段区间中,先后最优的和减去后手最优的和。

(即题目中的在原数组操作改为在 $i$ 到 $j$ 区间操作),

那么考虑一开始取最左还是最有

  1. 左端,取完后的区间为 $[i + 1, j]$,那么:$f_{i, j} = a_i - f_{i +1,j}$

  2. 右端,取完后的区间为 $[i, j - 1]$,那么 $f_{i, j} = a_j - f_{i, j - 1}$,

则先手会总上述方法中取最大,

所以,

$$f_{i, j} = \max (a_i - f_{i + 1,j},a_j - f_{i, j - 1})$$

初始化 :$f_{i, i} = a_i$,

#include <cstdio>
#include <iostream>
using namespace std;

const int N = 3010;

int a[N];

long long f[N][N];

int main() {
    int n; scanf ("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf ("%d", &a[i]);
        f[i][i] = a[i]; // 初始化
    }
    for (int d = 2; d <= n; ++d) { // 枚举区间长度
        for (int l = 1; l <= n - d + 1; ++l) { // 枚举左端点
            int r = l + d - 1;
            f[l][r] = max (a[l] - f[l + 1][r], a[r] - f[l][r - 1]);
        }
    }
    printf ("%lld", f[1][n]);
    return 0;
}
posted @ 2022-04-14 17:25  wangzhongyuan  阅读(16)  评论(0)    收藏  举报  来源