poj 3317 Stake Your Claim 极大极小搜索

思路:为了方便,当c1>c2时将0变为1,1变为0.

空格最多有10个,每个空格有3个状态,如果不状态压缩,会TLE的。所以最多有3^10种情况

代码如下:

  1 #include<iostream>
  2 #include<stdio.h>
  3 #include<algorithm>
  4 #include<iomanip>
  5 #include<cmath>
  6 #include<cstring>
  7 #include<vector>
  8 #include<map>
  9 #define inf 1<<30
 10 using namespace std;
 11 struct point
 12 {
 13     int x,y;
 14     point(){}
 15     point(int _x,int _y):x(_x),y(_y){}
 16 }pos[11],s;
 17 int move[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
 18 char str[9][10];
 19 int x,y,n,sum,ret,dp[60000],p[15];
 20 map<int ,int>mm;
 21 bool vis[9][9];
 22 void dfs(int x,int y)
 23 {
 24     if(vis[x][y]) return ;
 25     vis[x][y]=1;
 26     sum++;
 27     for(int i=0;i<4;i++){
 28         int a=x+move[i][0];
 29         int b=y+move[i][1];
 30         if(a>=0&&a<n&&b>=0&&b<n&&!vis[a][b]&&str[x][y]==str[a][b])
 31             dfs(a,b);
 32     }
 33 }
 34 int get_score()
 35 {
 36     memset(vis,0,sizeof(vis));
 37     int t1=0,t2=0;
 38     for(int i=0;i<n;i++)
 39     for(int j=0;j<n;j++){
 40         if(!vis[i][j]){
 41             sum=0;
 42             dfs(i,j);
 43             if(str[i][j]=='0') t1=max(t1,sum);
 44             else t2=max(t2,sum);
 45         }
 46     }
 47     return t1-t2;
 48 }
 49 int minimax(int ,int ,int ,int);
 50 int maxmini(int state,int now,int d,int mi)
 51 {
 52     if(!state) return get_score();
 53     if(dp[now]!=-inf) return dp[now];
 54     int ma=-inf,st=state,k,j;
 55     while(st){ //枚举所有的1的情况,也就是'.'的情况
 56         k=st&(-st); // 找到st倒数第一个1
 57         j=mm[k]; //1的位置
 58         str[pos[j].x][pos[j].y]='0';
 59         int t=minimax(state-k,now+p[j],d+1,ma);
 60         str[pos[j].x][pos[j].y]='.';
 61         ma=max(ma,t);
 62         if(ma>=mi) return ma;
 63         if(d==0){ //更新结果
 64             if(ret<ma||(ret==ma&&(s.x>pos[j].x||(s.x==pos[j].x&&s.y>pos[j].y)))){
 65                 s=pos[j];
 66                 ret=ma;
 67             }
 68         }
 69         st-=k; //继续枚举下一个1
 70     }
 71     return dp[now]=ma;
 72 }
 73 int minimax(int state,int now,int d,int ma)
 74 {
 75     if(!state) return get_score();
 76     if(dp[now]!=-inf) return dp[now];
 77     int mi=inf,k,st=state,j;
 78     while(st){
 79         k=st&(-st);
 80         j=mm[k];
 81         str[pos[j].x][pos[j].y]='1';
 82         int t=maxmini(state-k,now+2*p[j],d+1,mi);
 83         str[pos[j].x][pos[j].y]='.';
 84         mi=min(mi,t);
 85         if(mi<=ma) return mi;
 86         st-=k;
 87     }
 88     return dp[now]=mi;
 89 }
 90 int main()
 91 {
 92 //    freopen("1.txt","r",stdin);
 93     p[0]=1;
 94     for(int i=1;i<=10;i++) p[i]=3*p[i-1];
 95     for(int i=0;i<=11;i++) mm[(1<<i)]=i;
 96     while(scanf("%d",&n)&&n){
 97         int c1=0,c2=0,num=0;
 98         for(int i=0;i<n;i++){
 99             scanf("%s",str[i]);
100             for(int j=0;j<n;j++){
101                 if(str[i][j]=='0') c1++;
102                 else if(str[i][j]=='1') c2++;
103                 else pos[num++]=point(i,j);
104             }
105         }
106         if(c1>c2){   //始终让0先走
107             for(int i=0;i<n;i++)
108             for(int j=0;j<n;j++){
109                 if(str[i][j]=='0') str[i][j]='1';
110                 else if(str[i][j]=='1') str[i][j]='0';
111             }
112         }
113         for(int i=0;i<p[num];i++) dp[i]=-inf;
114         ret=-inf;
115         maxmini((1<<num)-1,0,0,inf);
116         printf("(%d,%d) %d
",s.x,s.y,ret);
117     }
118     return 0;
119 }
View Code
原文地址:https://www.cnblogs.com/xin-hua/p/3330666.html