题意
给出N个正整数,AB两个人轮流取数,A先取。每次可以取任意多个数,直到N个数都被取走。
每次获得的得分为取的数中的最小值,A和B的策略都是尽可能使得自己的得分减去对手的得分更大。
在这样的情况下,最终A的得分减去B的得分为多少。
N <= 1,000,000
分析
我们把所有数从小到大排好序后,很显然每次都是取最后面连续的一段。
我们不难发现从后往前推的话不是很好转移,那么就考虑从前往后转移。
设f[i]表示前i个数作为一组游戏的话先手-后手的最大值。
枚举第一次选哪个数,那么
f[i]=max(a[j]−f[j−1])(j<=i)
记录一个最大值即可。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1000005;
int n,a[N];
LL f[N];
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1);
LL mx=a[1];
for (int i=1;i<=n;i++)
{
f[i]=mx;mx=max(mx,a[i+1]-f[i]);
}
printf("%lld",f[n]);
return 0;
}