题目链接在此
递推公式:
由于玩家 1 可以任意选择在两头取数,因此要对玩家 1 每次的选择进行分类讨论。
1. 玩家 1 选择取最左边的数 array[ a ]
if (array[a + 1] >= array[b])
points1 = dp(a + 2, b) + array[a] - array[a + 1] (玩家 2 选择array[a + 1])
else
points1 = dp(a + 1, b - 1) + array[a] - array[b] (玩家 2 选择array[b])
2. 玩家 1 选择取最右边的数 array[ b ]
if (array[a] >= array[b - 1])
points2 = dp(a + 1, b - 1) + array[b] - array[a] (玩家 2 选择array[a])
else
points2 = dp(a, b - 2) + array[b] - array[b - 1] (玩家 2 选择array[b - 1])
那么,
d[a][b] = max(points1, points2)
由于玩家 1 可以任意选择在两头取数,因此要对玩家 1 每次的选择进行分类讨论。
1. 玩家 1 选择取最左边的数 array[ a ]
if (array[a + 1] >= array[b])
points1 = dp(a + 2, b) + array[a] - array[a + 1] (玩家 2 选择array[a + 1])
else
points1 = dp(a + 1, b - 1) + array[a] - array[b] (玩家 2 选择array[b])
2. 玩家 1 选择取最右边的数 array[ b ]
if (array[a] >= array[b - 1])
points2 = dp(a + 1, b - 1) + array[b] - array[a] (玩家 2 选择array[a])
else
points2 = dp(a, b - 2) + array[b] - array[b - 1] (玩家 2 选择array[b - 1])
那么,
d[a][b] = max(points1, points2)
<span style="font-size:18px;">#include <iostream>
#include <algorithm>
using namespace std;
const int INFINITE = 1000001;
int d[1100][1100];
int dp(int a, int b, int* array) {
if (d[a][b] != INFINITE)
return d[a][b];
if (a > b)
return 0;
if (array[a + 1] >= array[b]) {
if (array[a] >= array[b - 1])
d[a][b] = max(dp(a + 2, b, array) + array[a] - array[a + 1],
dp(a + 1, b - 1, array) + array[b] - array[a]);
else
d[a][b] = max(dp(a + 2, b, array) + array[a] - array[a + 1],
dp(a, b - 2, array) + array[b] - array[b - 1]);
}
else {
if (array[a] >= array[b - 1])
d[a][b] = max(dp(a + 1, b - 1, array) + array[a] - array[b],
dp(a + 1, b - 1, array) + array[b] - array[a]);
else
d[a][b] = max(dp(a + 1, b - 1, array) + array[a] - array[b],
dp(a, b - 2, array) + array[b] - array[b - 1]);
}
return d[a][b];
}
int main() {
int num;
int caseNum = 1;
cin >> num;
while (num != 0) {
int* array = new int[num + 1];
for (int i = 1; i <= num; i++)
for (int j = 1; j <= num; j++)
d[i][j] = INFINITE;
for (int i = 1; i <= num; i++)
cin >> array[i];
cout << "In game " << caseNum++
<< ", the greedy strategy might lose by as many as "
<< dp(1, num, array) << " points.\n";
delete[] array;
cin >> num;
}
return 0;
}</span>
<span style="font-size:18px;">#include <iostream>
#include <algorithm>
using namespace std;
const int INFINITE = 1000001;
int d[1100][1100];
int dp(int a, int b, int* array) {
if (d[a][b] != INFINITE)
return d[a][b];
if (a > b)
return 0;
if (array[a + 1] >= array[b]) {
if (array[a] >= array[b - 1])
d[a][b] = max(dp(a + 2, b, array) + array[a] - array[a + 1],
dp(a + 1, b - 1, array) + array[b] - array[a]);
else
d[a][b] = max(dp(a + 2, b, array) + array[a] - array[a + 1],
dp(a, b - 2, array) + array[b] - array[b - 1]);
}
else {
if (array[a] >= array[b - 1])
d[a][b] = max(dp(a + 1, b - 1, array) + array[a] - array[b],
dp(a + 1, b - 1, array) + array[b] - array[a]);
else
d[a][b] = max(dp(a + 1, b - 1, array) + array[a] - array[b],
dp(a, b - 2, array) + array[b] - array[b - 1]);
}
return d[a][b];
}
int main() {
int num;
int caseNum = 1;
cin >> num;
while (num != 0) {
int* array = new int[num + 1];
for (int i = 1; i <= num; i++)
for (int j = 1; j <= num; j++)
d[i][j] = INFINITE;
for (int i = 1; i <= num; i++)
cin >> array[i];
cout << "In game " << caseNum++
<< ", the greedy strategy might lose by as many as "
<< dp(1, num, array) << " points.\n";
delete[] array;
cin >> num;
}
return 0;
}</span>