刚开始没发现是DP,想了半天做错了- -,直接上代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n;
int num[1005];
int sum;
int f[1005][1005];
int dp(int begin, int end) {
if (f[begin][end] == 0) { // 防止重复搜索
if (begin == end - 1) { // 只剩下两个时贪心即可
return f[begin][end] = num[begin] > num[end] ? num[begin] : num[end];
}
int temp1 = num[begin]; // 拿了开头的
if (num[begin + 1] >= num[end]) { // 预判玩家2的行为,判断他会num[begin + 1]还是num[end], 然后递归
temp1 += dp(begin + 2, end);
}
else {
temp1 += dp(begin + 1, end - 1);
}
int temp2 = num[end]; // 拿了结尾的
if (num[end - 1] <= num[begin]) { // 同样预判玩家二的行为,并对剩下的递归
temp2 += dp(begin + 1, end - 1);
} else {
temp2 += dp(begin, end - 2);
}
f[begin][end] = temp1 > temp2 ? temp1 : temp2; // 比较那种得到值更大
return f[begin][end];
}
return f[begin][end];
}
int main() {
int count = 1;
while (scanf("%d", &n) && n) {
sum = 0;
memset(f, 0, sizeof(f));
for (int i = 0; i < n; i++) {
scanf("%d", &num[i]);
sum += num[i];
}
printf("In game %d, the greedy strategy might lose by as many as %d points.\n", count++, 2 * dp(0, n - 1) - sum);
}
}