P3507[POI2010]GRAThe Minima Game【dp,博弈论】

正题

题目链接:https://www.luogu.com.cn/problem/P3507


题目大意

\(n\)个数,没人轮流取若干个并获得取走的数中最小数的权值,两人的目标都是自己的权值\(-\)对方的权值最大,求先手的权值\(-\)后手的权值


解题思路

肯定是从大往小取,所以我们从小往大\(dp\)
\(f_{i,0/1}\)表示取了前\(i\)个,最后一步是先/后手。

然后有\(f_{i,0}=max\{f_{j,1}+a_{j+1}\}(j<i),f_{i,1}=min\{f_{j,0}-a_{j+1}\}(j<i)\)

记录一下最大值转移即可,时间复杂度\(O(n)\)

可以每次权值取反省去第二维。


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=1e6+10;
ll n,a[N],f[N][2];
int main()
{
    scanf("%lld",&n);
    for(ll i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    sort(a+1,a+1+n);
    for(ll i=1,maxs=0,mins=0;i<=n;i++){
        mins=min(mins,f[i-1][0]-a[i]);
        maxs=max(maxs,f[i-1][1]+a[i]);
        f[i][0]=maxs;f[i][1]=mins;
    }
    printf("%lld\n",f[n][0]);
}
原文地址:https://www.cnblogs.com/QuantAsk/p/14264367.html