时间复杂度: $O(n^2)$
博弈论的核心: 最坏情况下最好。
f[i][j]
表示在区间i到j,先手与后手的得分差值。
取左端点w[i] - f[i + 1][j]
;
取右端点w[j] - f[i][j - 1]
;
取他们最好的情况就行。所以状态转移方程:
f[i][j] = max(w[i] - f[i + 1][j], w[j] - f[i][j - 1]
;
f[0][n - 1]
为 $A - B$ 的得分。
求和$s = \sum{w_i}$ 为$A + B$ 的得分。
A的得分就是$\frac{s + f[0][n - 1]} {2}$;
B的得分就是$\frac{s - f[0][n - 1]} {2}$;
#include <iostream>
using namespace std;
const int N = 110;
int w[N];
int f[N][N];
int n;
int main()
{
cin >> n;
int sum = 0;
for (int i = 0; i < n; i ++) cin >> w[i], sum += w[i];
for (int len = 1; len <= n; len ++)
for (int i = 0; i + len - 1 < n; i ++)
{
int j = i + len - 1;
f[i][j] = max(w[i] - f[i + 1][j], w[j] - f[i][j - 1]);
}
cout << (sum + f[0][n - 1]) / 2 << ' ' << (sum - f[0][n - 1]) / 2 << endl;
return 0;
}