传送门 解题思路 比较容易的一道期望 \(dp\) ,设 \(f[i][j][k]\) 表示石头 \(i\) 个,剪刀 \(j\) 个,步子 \(l\) 个。然后转移的时候用组合数算一下就好了。 代码 #includeiostream#includecstdio#incl
传送门
解题思路
比较容易的一道期望\(dp\),设\(f[i][j][k]\)表示石头\(i\)个,剪刀\(j\)个,步子\(l\)个。然后转移的时候用组合数算一下就好了。
代码
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; const int MAXN = 105; int r,s,p; double f[MAXN][MAXN][MAXN],ans1,ans2,ans3; inline int calc(int x,int y,int z){ return max(((x+y+z)*(x+y+z-1)-x*(x-1)-y*(y-1)-z*(z-1))/2,1); } int main(){ scanf("%d%d%d",&r,&s,&p); f[r][s][p]=1.0; for(int i=r;i>=0;i--) for(int j=s;j>=0;j--) for(int l=p;l>=0;l--){ if(i==0 && j==0 && l==0) continue; if(i==r && j==s && l==p) continue; // cout<<i<<" "<<j<<" "<<l<<" "<<calc(i,j,l)<<endl; f[i][j][l]+=f[i+1][j][l]*((double)((i+1)*l)/calc(i+1,j,l)); f[i][j][l]+=f[i][j+1][l]*((double)((j+1)*i)/calc(i,j+1,l)); f[i][j][l]+=f[i][j][l+1]*((double)((l+1)*j)/calc(i,j,l+1)); } for(int i=1;i<=r;i++) ans1+=f[i][0][0]; for(int i=1;i<=s;i++) ans2+=f[0][i][0]; for(int i=1;i<=p;i++) ans3+=f[0][0][i]; printf("%.12lf %.12lf %.12lf",ans1,ans2,ans3); return 0; }