题目链接在此
递推公式:
由于玩家 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>
本文探讨了动态规划在解决区间内贪心策略导致双方分数最大差值问题的应用,通过分类讨论玩家1的选择策略来计算最大分数差,并提供了C++代码实现。
343

被折叠的 条评论
为什么被折叠?



