[POI2010]GRA-The Minima Game
[POI2010]GRA-The Minima Game
一道与博弈相关的dp,想了好长时间,才想明白。
A与B都是从大到小,取连续的一段,因为每次都是取当前拿走的元素的最小值。然后由小到大排序,f[i]表示两个人取完了,前i个元素,(先手-后手)的最大值,我一直卡在这里,我总是以为这里的先手就是A,后手就是B,正确的想法是先手与后手是相对的,在某次操作中,谁操作谁是先手,从这次操作转到下次状态,先后手会转换,f[i]=max(f[i-1],a[i]-f[i-1]);
答案就是f[n]。
#include<iostream> #include<cstdio> #include<queue> #include<algorithm> #include<cmath> #include<ctime> #include<cstring> #define inf 2147483647 #define For(i,a,b) for(register int i=a;i<=b;i++) #define p(a) putchar(a) #define g() getchar() //by war //2017.10.16 using namespace std; int a[1000010]; int f[1000010]; int n; void in(int &x) { int y=1; char c=g();x=0; while(c<'0'||c>'9') { if(c=='-') y=-1; c=g(); } while(c<='9'&&c>='0')x=x*10+c-'0',c=g(); x*=y; } void o(int x) { if(x<0) { p('-'); x=-x; } if(x>9)o(x/10); p(x%10+'0'); } int main() { in(n); For(i,1,n) in(a[i]); sort(a+1,a+n+1); For(i,1,n) f[i]=max(f[i-1],a[i]-f[i-1]); o(f[n]); return 0; }