既然没有大佬写题解那本蒟蒻就厚颜无耻地写( 水 )一( 经 )下( 验 )吧 题目要求算出个种人单独留下的存活率 因为n,m,p的范围极小, 那么就可以方便地设3位dp状态dp[i][j][k]表示剩余i个石
既然没有大佬写题解那本蒟蒻就厚颜无耻地写(水)一(经)下(验)吧
题目要求算出个种人单独留下的存活率
因为n,m,p的范围极小,
那么就可以方便地设3位dp状态dp[i][j][k]表示剩余i个石头,j个剪刀,k个布的概率
当前的相遇的总情况数为ij+ik+j*k
如果遇到的两个相同的人不发生变化转移可可以忽略
如果遇到不同的人 各自的情况分别为ij,ik,j*k
转移方以石头剪刀相遇为例转移方程就为ijdp[i][j-1][k] += (ij)/(ij+ik+jk)dp[i][j][k]
最后算出各自在其他人为0时自己从1到最大的概率累加起来
输出即可
代码
#include<bits/stdc++.h> using namespace std; #define ll long long #define C getchar()-48 inline ll read() { ll s=0,r=1; char c=C; for(;c<0||c>9;c=C) if(c==-3) r=-1; for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c; return s*r; } const int N=1e2+10; int n,m,p; double dp[N][N][N]; int main() { n=read(),m=read(),p=read(); dp[n][m][p]=1.0; for(int i=n;i>=0;i--) for(int j=m;j>=0;j--) for(int o=p;o>=0;o--) { if(i&&j) dp[i][j-1][o]+=(1.0*i*j/(i*j+j*o+i*o))*dp[i][j][o]; if(j&&o) dp[i][j][o-1]+=(1.0*j*o/(i*j+j*o+i*o))*dp[i][j][o]; if(i&&o) dp[i-1][j][o]+=(1.0*i*o/(i*j+j*o+i*o))*dp[i][j][o]; } double ed1=0,ed2=0,ed3=0; for(int i=1;i<=n;i++) ed1+=dp[i][0][0]; for(int j=1;j<=m;j++) ed2+=dp[0][j][0]; for(int o=1;o<=p;o++) ed3+=dp[0][0][o]; printf("%.10f %.10f %.10f\n",ed1,ed2,ed3); return 0; }