AT4533
容易想到区间 dp,
设 $f_{i, j}$ 表示 $i$ 到 $j$ 这段区间中,先后最优的和减去后手最优的和。
(即题目中的在原数组操作改为在 $i$ 到 $j$ 区间操作),
那么考虑一开始取最左还是最有
-
左端,取完后的区间为 $[i + 1, j]$,那么:$f_{i, j} = a_i - f_{i +1,j}$
-
右端,取完后的区间为 $[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;
}
浙公网安备 33010602011771号