这题用动态规划,对手一直采取选最大数字的策略,对手策略固定,于是可以计算
(1)取左边的数,减去对手取最大数,再加上在剩下数中取得的最大分差(递归计算)
(2)取右边的数,减去对手取最大数,再加上在剩下数中取得的最大分差(递归计算)
不过递归会超时,所以可以用一个二维数组记录下来已经算过的结果,如dif[a][b]表示从a到b能取得的最大分差
代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int maxdif[1500][1500];
int max_dif(int a, int b, int num[],int maxdif[][1500])
{
//b == a+1
if(b - a <= 1)
return num[b]>num[a]?num[b]-num[a]:num[a]-num[b];
if(maxdif[a][b] != 1100000)
{
return maxdif[a][b];
}
//b>a+1
//choose a
int max1;
if(num[a+1]>=num[b])
{
max1 = num[a] + max_dif(a+2,b,num,maxdif) - num[a+1];
}
else
{
max1 = num[a] + max_dif(a+1,b-1,num,maxdif) - num[b];
}
//choose b
int max2;
if(num[a]>=num[b-1])
{
max2 = num[b] + max_dif(a+1,b-1,num,maxdif) - num[a];
}
else
{
max2 = num[b] + max_dif(a,b-2,num,maxdif) - num[b-1];
}
maxdif[a][b] = max1>max2?max1:max2;
return maxdif[a][b];
}
int main()
{
int n;
int count = 1;
while(cin >> n && n != 0)
{
int a[1005];
//int sum = 0;
for(int i = 0; i < n; i++)
{
cin >> a[i];
//sum += a[i];
for(int j = 0; j < 1500; j++)
{
maxdif[j][i] = 1100000;
}
}
int dif = max_dif(0,n-1,a,maxdif);
printf("In game %d, the greedy strategy might lose by as many as %d points.\n", count++, dif);
}
}