大概可以这样理解, 一开始有r个石头, p个布, s个剪刀, 每一天有其中的两个相遇, 如果两个是相同的种类, 什么都不会发生, 否则的话有一个会挂掉, 问最后每一种生存的概率。
dp[i][j][k]表示到达i个石头, j个布, s个剪刀的概率, 那么初始状态dp[r][p][s] = 1。 状态转移方程为dp[i-1][j][k] = i*k/tot*dp[i][j][k], tot是当前所有相遇的情况, tot = i*j+i*k+j*k。
最后求每一种的生存的概率, 如果是石头生存, 那么显然只要布为0, 石头的个数>0, 而剪刀的个数无论有多少个都可以。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_pair(x, y) 6 #define lson l, m, rt<<1 7 #define mem(a) memset(a, 0, sizeof(a)) 8 #define rson m+1, r, rt<<1|1 9 #define mem1(a) memset(a, -1, sizeof(a)) 10 #define mem2(a) memset(a, 0x3f, sizeof(a)) 11 #define rep(i, a, n) for(int i = a; i<n; i++) 12 #define ull unsigned long long 13 typedef pair<int, int> pll; 14 const double PI = acos(-1.0); 15 const double eps = 1e-8; 16 const int mod = 1e9+7; 17 const int inf = 1061109567; 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 19 double dp[101][101][101]; 20 int main() 21 { 22 int a, b, c; 23 cin>>a>>b>>c; 24 mem(dp); 25 dp[a][b][c] = 1.0; 26 for(int i = a; i>=1; i--) { 27 for(int j = b; j>=1; j--) { 28 for(int k = c; k>=1; k--) { 29 double tot = i*j+j*k+i*k; 30 dp[i-1][j][k] += 1.0*(i*k)/tot*dp[i][j][k]; 31 dp[i][j-1][k] += 1.0*(j*i)/tot*dp[i][j][k]; 32 dp[i][j][k-1] += 1.0*(j*k)/tot*dp[i][j][k]; 33 } 34 } 35 } 36 double ans1 = 0, ans2 = 0, ans3 = 0; 37 for(int i = 1; i<=a; i++) 38 for(int j = 0; j<=b; j++) 39 ans1 += dp[i][j][0]; 40 for(int i = 1; i<=b; i++) 41 for(int j = 0; j<=c; j++) 42 ans2 += dp[0][i][j]; 43 for(int i = 1; i<=c; i++) 44 for(int j = 0; j<=a; j++) 45 ans3 += dp[j][0][i]; 46 printf("%.9f %.9f %.9f ", ans1, ans2, ans3); 47 }