这对抗搜索是个啥玩意儿……
首先可以发现每一行的棋子数都不小于下一行,且局面可由每一行的棋子数唯一表示,那么用一个m+1进制数来表示当前局面,用longlong存,开map记忆化搜索
然后时间复杂度的问题,rqy这样说的
然后这个对抗搜索的话……个人理解就是因为要最大化分值的差,所以在一个人下棋的时候令他得分最大,另一个人得分最小
1 //minamoto 2 #include<cstdio> 3 #include<iostream> 4 #include<map> 5 #define ll long long 6 using namespace std; 7 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++) 8 char buf[1<<21],*p1=buf,*p2=buf; 9 template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;} 10 template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;} 11 inline int read(){ 12 #define num ch-‘0‘ 13 char ch;bool flag=0;int res; 14 while(!isdigit(ch=getc())) 15 (ch==‘-‘)&&(flag=true); 16 for(res=num;isdigit(ch=getc());res=res*10+num); 17 (flag)&&(res=-res); 18 #undef num 19 return res; 20 } 21 const int N=15,base=12,inf=0x3f3f3f3f; 22 map<ll,int> mp;int a[N][N],b[N][N],bl[N],n,m; 23 inline ll hsh(){ 24 ll res=0; 25 for(int i=1;i<=n;++i) res=res*base+bl[i]; 26 return res; 27 } 28 inline void unzip(ll S){ 29 for(int i=n;i;--i) bl[i]=S%base,S/=base; 30 } 31 inline int getnxt(){ 32 int res=0; 33 for(int i=1;i<=n;++i) res+=bl[i]; 34 return res&1; 35 } 36 int dfs(ll S){ 37 if(mp.find(S)!=mp.end()) return mp[S]; 38 unzip(S); 39 int type=getnxt(),res=type?inf:-inf; 40 for(int i=1;i<=n;++i) 41 if(bl[i-1]>bl[i]){ 42 ++bl[i];ll h=hsh(); 43 type?cmin(res,dfs(h)-b[i][bl[i]]):cmax(res,dfs(h)+a[i][bl[i]]); 44 --bl[i]; 45 } 46 return mp[S]=res; 47 } 48 int main(){ 49 // freopen("testdata.in","r",stdin); 50 n=read(),m=read(),bl[0]=m; 51 for(int i=1;i<=n;++i) 52 for(int j=1;j<=m;++j) 53 a[i][j]=read(); 54 for(int i=1;i<=n;++i) 55 for(int j=1;j<=m;++j) 56 b[i][j]=read(); 57 for(int i=1;i<=n;++i) bl[i]=m; 58 ll full=hsh();mp[full]=0; 59 dfs(0); 60 printf("%d\n",mp[0]); 61 return 0; 62 }
原文地址:https://www.cnblogs.com/bztMinamoto/p/9746678.html
时间: 2024-11-08 20:04:34