用九元组表示当前状态,即每队牌剩的张数,状态总数为5^9=1953125.
设d[ i ]表示状态i对应的成功概率,则根据全概率公式,d[ i ]为后继成功概率的平均值,按照动态规划的写法计算即可。
这个动态规划我不会写,帅哥思路真的很清晰很好啊。
但是学会还是很高兴的
#include<cstdio> #include<vector> #include<cstring> #include<algorithm> using namespace std; #define mem(a) memset(a,0,sizeof(a)) vector<char> v[9]; double d[5][5][5][5][5][5][5][5][5]; int vis[5][5][5][5][5][5][5][5][5]; double dp(int t0,int t1,int t2,int t3,int t4,int t5,int t6,int t7,int t8) { double& ans=d[t0][t1][t2][t3][t4][t5][t6][t7][t8]; if(vis[t0][t1][t2][t3][t4][t5][t6][t7][t8]) return ans; vis[t0][t1][t2][t3][t4][t5][t6][t7][t8]=1; int te[9]={t0,t1,t2,t3,t4,t5,t6,t7,t8}; int ok=1; for(int i=0;i<9;i++) if(te[i]){ok=0; break;} if(ok) return ans=1; ans=0; int num=0; double pum=0; for(int i=0;i<9;i++) if(te[i]) for(int j=i+1;j<9;j++) if(te[j]&&v[i][te[i]-1]==v[j][te[j]-1]) { num++; te[i]--; te[j]--; pum+=dp(te[0],te[1],te[2],te[3],te[4],te[5],te[6],te[7],te[8]); te[i]++; te[j]++; } if(num==0) return ans=0; else return ans = pum/(num*1.0); } int main() { char s[5]; while(scanf("%s",s)!=EOF) { mem(d); mem(vis); for(int i=0;i<9;i++) v[i].clear(); v[0].push_back(s[0]); for(int i=1;i<=3;i++) { scanf("%s",s); v[0].push_back(s[0]); } for(int i=1;i<9;i++) { for(int j=1;j<=4;j++) { scanf("%s",s); v[i].push_back(s[0]); } } printf("%lf\n",dp(4,4,4,4,4,4,4,4,4)); } return 0; }
定义状态的方法和状态转移的方法都很好,要学习。
方法值得常思考常学习~
1637 - Double Patience(状态转移+求成功概率)
时间: 2024-10-14 03:46:58