【题意】两个人轮番从n个数中每次选择任意个数, 每次获得的分数是所选数种最小的,两人采取的策略都是使得自己的分数减去对方的分数尽量大, 求最终第一个人的得分。

【解题方法】由于每个人都是从大往小拿,先将序列排序。由于得分是最小值,我们不妨反向思考,f[i]:=剩余i个数,先手得分−后手得分的最大值。转移就看这个数先手取还是不取,不取则f[i−1],取则a[i]−f[i−1],ans=f[n]。

【AC 代码】

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=5e4+10;
typedef long long LL;
int a[N];
LL dp[N];
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&n);
        for(int i=1; i<=n; i++) scanf("%d",&a[i]);
        sort(a+1,a+1+n);
        for(int i=1; i<=n; i++){
            dp[i]=max(dp[i-1],a[i]-dp[i-1]);
        }
        printf("%I64d\n",dp[n]);
    }
}