[九省联考2018]一双木棋chess
SOL:
我们发现轮廓线一定是单调不减的。 所以这个博弈的总状态数只有10C20 种呢。
算一下 有184756 种状态,大力dp一下就好了啦。
#include<bits/stdc++.h> #define LL long long #define inf (1ll<<51) #define sight(x) ('0'<=x&&x<='9') using namespace std; inline void read(int &x){ static char c; for (c=getchar();!sight(c);c=getchar()); for (x=0;sight(c);c=getchar())x=x*10+c-48; } void write(int x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);} inline void writeln(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('\n'); } inline void writel(int x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); } map<LL,int> dp; LL pd; int a[17][17],n,m,b[17],x,sum; inline LL Hash(){ static LL anw,i; for (anw=0,i=1;i<=n;i++) anw=anw*11+b[i]; return anw; } inline void push(LL anw) { for (int i=n;i;i--) b[i]=anw%11,anw/=11; } LL dfs(LL x){ if (dp.count(x)) return dp[x]; push(x); LL ha,t,res; t=1; for (int i=1;i<=n;i++) t^=b[i]&1; if (t) res=inf; else res=-inf;// 先手试图min for (int i=1;i<=n;i++) if (b[i-1]>b[i]){ b[i]++; ha=Hash(); if (t) res=min(dfs(ha),res); else res=max(dfs(ha)+a[i][b[i]],res); b[i]--; } return dp[x]=res; } signed main () { // freopen("chess.in","r",stdin); read(n); read(m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) read(a[i][j]),sum+=a[i][j]; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) read(x),a[i][j]+=x; b[0]=m; for (int i=1;i<=n;i++) pd=pd*11+m; dp[pd]=0; writeln(sum-dfs(0)); return 0; }