极大极小搜索+alpha_beta剪枝)

来源:互联网 发布:口译训练软件 编辑:程序博客网 时间:2024/05/27 03:25

http://poj.org/problem?id=1085

状态dp搜索

#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;int dps[1<<12][2];int mark[18];vector<int>vec[18];bool vis[18];int cnt;int tri[9][3]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,3,5,7,6,11,13,9,14,16};int mp[10][10]={0,0,1, 0, 0, 0, 0, 0, 0, 0,0,0,2, 3, 4, 0, 0, 0, 0, 0,1,2,0, 0, 6, 7, 0, 0, 0, 0,0,3,0, 0, 5, 0, 9,10, 0, 0,0,4,6, 5, 0, 8, 0,12,13, 0,0,0,7, 0, 8, 0, 0, 0,15,16,0,0,0, 9, 0, 0, 0,11, 0, 0,0,0,0,10,12, 0,11, 0,14, 0,0,0,0, 0,13,15, 0,14, 0,17,0,0,0, 0, 0,16, 0, 0,17, 0};int check(int x){int cou=0;for(int i=0;i<vec[x].size();i++){if(vis[tri[vec[x][i]][0]] && vis[tri[vec[x][i]][1]] && vis[tri[vec[x][i]][2]]) cou++;}return cou;}int dfs(int sta,int who){if(dps[sta][who]!=-10000) return dps[sta][who];if(sta==(1<<cnt)-1) return 0;if(who){int newbeta=10000;for(int i=0;i<cnt;i++){if(!(sta&(1<<i))){vis[mark[i]]=1;int tmp=check(mark[i]);if(tmp) newbeta=min(newbeta,-tmp+dfs(sta|(1<<i),who));else newbeta=min(newbeta,-tmp+dfs(sta|(1<<i),!who));vis[mark[i]]=0;}}dps[sta][who]=newbeta;return newbeta;}else{int newalpha=-10000;for(int i=0;i<cnt;i++){if(!(sta&(1<<i))){vis[mark[i]]=1;int tmp=check(mark[i]);if(tmp) newalpha=max(newalpha,tmp+dfs(sta|(1<<i),who));else newalpha=max(newalpha,tmp+dfs(sta|(1<<i),!who));vis[mark[i]]=0;}}dps[sta][who]=newalpha;return newalpha;}}void init(){for(int i=0;i<9;i++) for(int j=0;j<3;j++) tri[i][j]--;for(int i=0;i<9;i++) for(int j=0;j<3;j++) vec[tri[i][j]].push_back(i);}int main(){init();int T;scanf("%d",&T);for(int t=0;t<T;t++){int n;scanf("%d",&n);memset(vis,0,sizeof(vis));memset(mark,0,sizeof(mark));int turn=0,x=0,y=0;for(int i=0;i<n;i++){int u,v;scanf("%d %d",&u,&v);u--,v--;vis[mp[u][v]]=1;int tmp=check(mp[u][v]);if(turn) y+=tmp;else x+=tmp;if(!tmp) turn=!turn;}cnt=0;for(int i=0;i<18;i++) if(!vis[i]) mark[cnt++]=i;for(int i=0;i<(1<<12);i++) dps[i][0]=dps[i][1]=-10000;int tmp=dfs(0,turn); //我在这逗逼一下午,当n为18时dp[0][turn]=-10000;if(tmp+x-y>=0) printf("Game %d: A wins.\n",t+1); else printf("Game %d: B wins.\n",t+1);}    return 0;}


38界ACM杭州站I题 HDU 4778

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;int g,b,s;int bag[25][10];int dps[1<<21][2];int sum[1<<21];int dfs(int sta,int last,int who,int alpha,int beta){    int tmp=0,cha=0;    tmp=sum[sta]-sum[last];    if(who) cha-=tmp;else cha+=tmp;    if(!tmp) who=!who;    if(dps[sta][who]!=-10000) return cha+dps[sta][who];    if(who){        if(sta==(1<<b)-1) return cha;        int newbeta=10000;        bool flag=1;        for(int i=0;i<b;i++) if(!(sta&(1<<i))){        newbeta=min(newbeta,dfs(sta|(1<<i),sta,who,-10000,newbeta));if(newbeta<=alpha){flag=0;break;}        }        if(flag)dps[sta][who]=newbeta;        return newbeta+cha;    }    else{        if(sta==(1<<b)-1) return cha;        int newalpha=-10000;        bool flag=1;        for(int i=0;i<b;i++) if(!(sta&(1<<i))){        newalpha=max(newalpha,dfs(sta|(1<<i),sta,who,newalpha,10000));if(beta<=newalpha){flag=0;break;}        }        if(flag)dps[sta][who]=newalpha;        return newalpha+cha;    }}int main(){    while(scanf("%d %d %d",&g,&b,&s)){        if(g==0 && b==0 && s==0) break;        memset(bag,0,sizeof(bag));        for(int i=0;i<b;i++){            int n;            scanf("%d",&n);            for(int j=0;j<n;j++){                int tmp;                scanf("%d",&tmp);                tmp--;                bag[i][tmp]++;            }        }        int tmp[10];        for(int i=0;i<(1<<b);i++){            for(int j=0;j<g;j++) tmp[j]=0;            sum[i]=0;            for(int j=0;j<b;j++) if(i&(1<<j)){                for(int k=0;k<g;k++) tmp[k]+=bag[j][k];            }            for(int k=0;k<g;k++) sum[i]+=tmp[k]/s;        }        for(int i=0;i<(1<<b);i++) dps[i][0]=dps[i][1]=-10000;        dfs(0,0,1,-10000,10000);        printf("%d\n",dps[0][0]);    }    return 0;}


原创粉丝点击