十分有趣的问题.
我们发现如果拿的话肯定要先拿一些大的.
所以我们可以先将所有数从小到大排序,令 $f[i]$ 表示拿完前 $i$ 小先手-后手的最大值.
则有转移:$f[i]=max(f[i-1],a[i]-f[i-1])$
反复阅读:每次拿一些数字的贡献是这些数字中最小的值.
反复阅读上一句话,然后再看一看式子就容易懂了.
code:
#include <bits/stdc++.h>
#define N 1000006
#define ll long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
ll f[N],a[N];
int main()
{
// setIO("input");
int i,j,n;
scanf("%d",&n);
for(i=1;i<=n;++i) scanf("%lld",&a[i]);
sort(a+1,a+1+n);
for(i=1;i<=n;++i)
{
f[i]=max(f[i-1],a[i]-f[i-1]);
}
printf("%lld\n",f[n]);
return 0;
}
本文探讨了在算法竞赛中使用博弈论解决特定类型问题的方法。通过将数字按大小排序,并定义递推公式来计算先手和后手的最大得分差距,文章详细解释了一个有趣的博弈策略。代码示例展示了如何在C++中实现这一策略。
1765

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



