状态压缩,记忆化搜索。
用一个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; }
时间: 2024-12-17 13:29:50