Codeforces problem 540 D
题意:有三种人,石头剪刀布,各有r,s,p个,每天有2个不同种族的人出来决一胜负,活的人回去,问各个种族活下来的概率
思路:dp[i][j][k]为石头有i个,剪刀有j个,布有k个的概率 那么石头的概率就是dp[1][0][0]+......dp[r][0][0]了
状态转移:当前有(i+j+k)*(i+j+k-1)/2-i*(i-1)/2-j*(j-1)/2-k*(k-1)中选人方案sum
石头和剪刀打: dp[i][j-1][k]+=dp[i][j][k]*i*j/sum
剪刀和布打: dp[i][j][k-1]+=dp[i][j][k]*j*k/sum
石头和布打 :dp[i-1][j][k]+=dp[i][j][k]*k*i/sum;
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 double dp[110][110][110]; 5 6 int main(){ 7 int r,s,p; 8 cin>>r>>s>>p; 9 dp[r][s][p]=1; 10 double ans1=0,ans2=0,ans3=0; 11 for(int i=r;i>=0;i--){//石头 12 for(int j=s;j>=0;j--){//剪刀 13 for(int k=p;k>=0;k--){//布 14 double tmp=(i+j+k)*(i+j+k-1)/2-i*(i-1)/2-j*(j-1)/2-k*(k-1)/2; 15 if (j>0&&i>0) 16 dp[i][j-1][k]+=dp[i][j][k]*i*j/tmp; 17 if (j>0&&k>0) 18 dp[i][j][k-1]+=dp[i][j][k]*j*k/tmp; 19 if (i>0&&k>0) 20 dp[i-1][j][k]+=dp[i][j][k]*k*i/tmp; 21 } 22 } 23 } 24 for(int i=0;i<=r;i++){ 25 //printf("%.4lf\n",dp[i][0][0]); 26 ans1+=dp[i][0][0]; 27 } 28 for(int j=1;j<=s;j++) 29 ans2+=dp[0][j][0]; 30 for(int k=1;k<=p;k++) 31 ans3+=dp[0][0][k]; 32 printf("%.9lf %.9lf %.9lf\n",ans1,ans2,ans3); 33 }