Vijos2034
这是极大极小值算法原理,不断递归
alpha_bata算法是对其的一个优化
当当前这轮选的是答案尽量大的值时(pro_max),到(pro_min)里搜索时,去的是尽量小的值,若当前能取到比在pro_max平行的前几轮里更小的,则pro_max里即可避免掉这种方案,取前几种方案
pro_min同理
//开了rigister 后快了0.7s #include<cstdio> #include<cctype> #include<algorithm> #define INF 1000000007 using namespace std; int a[4][4],k,sum,tot; inline void read(int &x){ char ch=getchar();x=0;int f=1; while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} x*=f; } void ratal(int x,int y){ int tmp=a[x][y]; a[x][y]=a[x][y+1]; a[x][y+1]=a[x+1][y+1]; a[x+1][y+1]=a[x+1][y]; a[x+1][y]=tmp; sum+=a[x][y]+a[x+1][y]+a[x][y+1]+a[x+1][y+1]; } void ratar(int x,int y){ int tmp=a[x][y]; a[x][y]=a[x+1][y]; a[x+1][y]=a[x+1][y+1]; a[x+1][y+1]=a[x][y+1]; a[x][y+1]=tmp; sum-=(a[x][y]+a[x+1][y]+a[x][y+1]+a[x+1][y+1]); } int pro_max(int dep,int alph,int bet); int pro_min(int dep,int alph,int bet); int pro_max(int dep,int alph,int bet){ if(dep==k)return sum; pair<int,int>f[9]; for(register int i=0;i<3;i++) for(register int j=0;j<3;j++){ f[i*3+j]=make_pair(a[i][j]+a[i][j+1]+a[i+1][j]+a[i+1][j+1],i*3+j); } sort(f,f+9); for(register int i=8;i>=0;i--){ int x=f[i].second/3,y=f[i].second%3; ratal(x,y); int val=pro_min(dep+1,alph,bet); ratar(x,y); if(val>=bet)return bet; if(val>alph)alph=val; } return alph; } int pro_min(int dep,int alph,int bet){ if(dep==k)return sum; pair<int,int>f[9]; for(register int i=0;i<3;i++) for(register int j=0;j<3;j++){ f[i*3+j]=make_pair(a[i][j]+a[i][j+1]+a[i+1][j]+a[i+1][j+1],i*3+j); } sort(f,f+9); for(register int i=0;i<=8;i++){ int x=f[i].second/3,y=f[i].second%3; ratal(x,y); int val=pro_max(dep+1,alph,bet); ratar(x,y); if(val<=alph)return alph; if(val<bet)bet=val; } return bet; } int main(){ int T; read(T); while(T--){ read(k);k*=2; for(register int i=0;i<4;i++)for(register int j=0;j<4;j++)read(a[i][j]); printf("%d\n",pro_max(0,0,INF)); } }