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\n",s.x,s.y,ret);

117     }

118     return 0;

119 }
View Code

 

 

 

你可能感兴趣的:(poj)