pku3317 Stake Your Claim 极大极小搜索+状压+AB剪枝

来源:互联网 发布:淘宝预包装及散装食品 编辑:程序博客网 时间:2024/05/16 19:00

感觉我已经快不行惹 感觉自己有点弱竟然写了2h= =

开始并没发现可以状压【英语渣没看懂题目,后来偷窥了一下大神博客,发现空的格子不超过10个,于是我们考虑状压,三进制分别表示空格,0,1,四进制最开始以为开不下= =

然后我们传递还有哪些空格还没被选过,二进制高效处理,新姿势:用pos=log(k+0.5)/log(2.0)或者pos=log(k-0.5)/log(2.0)+1来获取是哪一位

AB剪枝,在搜索某个节点的子树过程中,发现当前子树怎样也无法得到比“当前已搜索过的子树得到的结果”(alpha或者beta)更优的结果时return那个值就行,切记不可把值传给f[now]。

时间复杂度O(n*n*2^m)剪枝或者状压后就可以过惹

Problem: 3317User: BPM136Memory: 2768KTime: 172MSLanguage: G++Result: Accepted#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<cstdlib>#include<algorithm>#include<bitset>#define LL long long#define get(i,j) (i*n+j)#define fo(i,a,b) for(int i=a;i<=b;i++)#define down(i,a,b) for(int i=a;i>=b;i--)using namespace std;inline LL read(){LL d=0,f=1;char s=getchar();while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}return d*f;}#define N 10#define MIN -10000#define MAX 10000struct point{int x,y;point(){x=y=0;}point(int x_,int y_){x=x_;y=y_;}}d[100],ans;int map[N][N];int n,nd=0,anss;int po[21];int f[1<<20];char s[100];bitset<100>v;int pri[4][2];int dfs(int x,int y,int k){if(x<0||y<0||x>=n||y>=n)return 0;if(v[get(x,y)])return 0;if(map[x][y]!=k)return 0;v[get(x,y)]=1;int t=1;fo(i,0,3)t+=dfs(x+pri[i][0],y+pri[i][1],k);return t;}int getvalue(int now){v.reset();int st=now;fo(i,0,nd-1){int t=st%3;st/=3;map[d[i].x][d[i].y]=t;}int ans0=0,ans1=0;fo(i,0,n-1){fo(j,0,n-1){//cout<<get(i,j)<<' '<<i<<' '<<j<<' '<<map[i][j]<<endl;if(v[get(i,j)]==0){//cout<<1222<<endl;int t=dfs(i,j,map[i][j]);//cout<<"suess"<<endl;if(map[i][j]==1){ans0=max(ans0,t);}else{ans1=max(ans1,t);}}}}fo(i,0,nd-1){map[d[i].x][d[i].y]=0;}return ans0-ans1;}int minimax(int status,int dep,int now,int beta);int maxmini(int status,int dep,int now,int alpha);int minimax(int status,int dep,int now,int beta){if(status==0)return getvalue(now);if(f[now]!=MIN)return f[now];int mi=MAX;int st=status;while(st){int k=st&(-st);int pos=log(k+0.5)/log(2.0);int t=maxmini(status-k,dep+1,now+po[pos]*2,mi);mi=min(mi,t);if(mi<=beta)return mi;st-=k;}return f[now]=mi;}int maxmini(int status,int dep,int now,int alpha){if(status==0)return getvalue(now);if(f[now]!=MIN) return f[now];int ma=MIN;int st=status;while(st){int k=st&(-st);int pos=log(k+0.5)/log(2.0);int t=minimax(status-k,dep+1,now+po[pos],ma);ma=max(ma,t);if(ma>=alpha)return ma;if(status==(1<<nd)-1){if(ma>anss){ans=d[pos];anss=ma;}}st-=k;}return f[now]=ma;}void init(){int c1=0,c0=0;nd=0;memset(map,0,sizeof(map));fo(i,0,n-1){scanf("%s",s);fo(j,0,n-1){if(s[j]=='.'){map[i][j]=0;d[nd++]=point(i,j);}elseif(s[j]=='0'){map[i][j]=1,c0++;}elseif(s[j]=='1'){map[i][j]=2,c1++;}}}if(c0>c1){fo(i,0,n-1){fo(j,0,n-1)if(map[i][j]){map[i][j]^=3;}}}fo(i,0,1<<20-1)f[i]=MIN;    ans=point(0,0);anss=MIN;}void check(){fo(i,0,n-1){fo(j,0,n-1)cout<<map[i][j];cout<<endl;}cout<<endl;}int main(){int tt=0;fo(i,-1,1)fo(j,-1,1)if(abs(i-j)==1){pri[tt][0]=i,pri[tt++][1]=j;}po[0]=1;nd=0;fo(i,1,10)po[i]=po[i-1]*3;while(scanf("%d",&n)!=EOF&&n){init();//check();maxmini((1<<nd)-1,0,0,MAX);printf("(%d,%d) %d\n",ans.x,ans.y,anss);fo(i,0,nd-1)d[i]=point(0,0);nd=0;}return 0;}




0 0
原创粉丝点击