E39 概率DP 求概率
视频链接:https://www.bilibili.com/video/BV1Ng4y177tX/
状态:f[i][j]表示袋中有i只白鼠j只黑鼠时,A获胜的概率
起点:f[0][i]=0,f[i][0]=1
终点:f[w][b]
转移:
1.先手拿到白鼠:f[i][j]+=i/(i+j)
2.先手黑鼠,后手白鼠:f[i][j]+=0, 这种情况不用处理
3.先手黑鼠,后手黑鼠,跑白鼠:f[i][j]+=j/(i+j) *(j-1)/(i+j-1) *i/(i+j-2) *f[i-1][j-2]
4.先手黑鼠,后手黑鼠,跑黑鼠:f[i][j]+=j/(i+j) *(j-1)/(i+j-1) *(j-2)/(i+j-2) *f[i][j-3]
#include <iostream> #include <cstring> #include <algorithm> using namespace std; int w, b; double f[1010][1010]; int main(){ scanf("%d %d", &w, &b); for(int i=1; i<=b; i++) f[0][i]=0; for(int i=1; i<=w; i++) f[i][0]=1; for(int i=1; i<=w; i++){ //白鼠 for(int j=1; j<=b; j++){ //黑鼠 f[i][j]+=(double)i/(i+j); if(i>=1 && j>=2) f[i][j]+=(double)j/(i+j)*(j-1)/(i+j-1)*i/(i+j-2)*f[i-1][j-2]; if(j>=3) f[i][j]+=(double)j/(i+j)*(j-1)/(i+j-1)*(j-2)/(i+j-2)*f[i][j-3]; } } printf("%.9lf\n", f[w][b]); }
题意:有2^n支球队比赛,每次和相邻的球队踢,两两淘汰,给定任意两支球队相互踢赢的概率,求最后哪只球队最可能夺冠
#include <iostream> #include <cstring> #include <algorithm> using namespace std; double p[130][130]; double f[8][130]; int main(){ int n; while(scanf("%d",&n),n!=-1){ int m=1<<n; for(int i=0;i<m;i++) for(int j=0;j<m;j++) scanf("%lf",&p[i][j]); memset(f,0,sizeof(f)); for(int i=0;i<m;i++) f[0][i]=1; for(int i=1;i<=n;i++) //第i轮 for(int j=0;j<m;j++) //第j队 for(int k=0;k<m;k++) //对手队 if(((j>>(i-1))^1) == (k>>(i-1))) f[i][j]+=f[i-1][j]*f[i-1][k]*p[j][k]; int ans; double mx=0; for(int i=0;i<m;i++) if(f[n][i]>mx) ans=i, mx=f[n][i]; printf("%d\n",ans+1); } }
练习: