uva1637Double Patience

状态压缩,记忆化搜索。

用一个5进制数来表示每堆排到了哪一个位置。和2进制是一样的,不过不能用位运算。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 2000000+10;

double dp[maxn];
bool vis[maxn];
char s[10][10][5];
int v,v2;

double dfs(int n) {
    v++;
    if(n==0) return 1.0;    
    if(vis[n]) {v2++; return dp[n];}
    vis[n]=1;
    
    int tmp=n,cnt=0;
    int a[10];
    for(int i=1;i<=9;i++) {
        a[i]=tmp%5;
        tmp/=5;
    }    
    for(int i=1;i<9;i++)
        for(int j=i+1;j<=9;j++) 
            if(a[i] && a[j] && s[i][a[i]][0]==s[j][a[j]][0]) {
                tmp=0;
                for(int k=9;k>=1;k--) {
                    tmp*=5;
                    if(k==i || k==j) tmp+=a[k]-1;
                    else tmp+=a[k];                
                }
                dp[n]+=dfs(tmp);
                cnt++;
            }    
    if(cnt) dp[n]=dp[n]/(1.0*cnt);
    return dp[n];
}

int main() {
    while(scanf("%s",s[1][1])==1) {
        for(int i=2;i<=4;i++) scanf("%s",s[1][i]);
        for(int i=2;i<=9;i++)
        for(int j=1;j<=4;j++) 
            scanf("%s",s[i][j]);
        memset(dp,0,sizeof(dp));
        memset(vis,0,sizeof(vis));
        dfs(1953124);
        printf("%.6lf\n",dfs(1953124));
    }
    return 0;
}
posted @ 2016-06-11 22:48  invoid  阅读(160)  评论(0编辑  收藏  举报