Bad Luck Island CodeForces - 540D

题意

一座岛上有三个种族的人,分别是paper, scissors, rock。

他们之间任意两人会接触。

如果他们不属于同一种族,那么他们按照石头剪子布的规则,败的人被杀死。

求岛上只剩下某一种族的人的概率。

分析

似乎可以跑三维DP, 因为每种人都最多100个。

\(dp[i][j][k]\)表示三种人分别有\(i\)个,\(j\)个,\(k\)个的状态的概率。

答案就是某种种族人数大于\(0\),其余种族人数为\(0\)的概率之和。

考虑\(dp[i][j][k]\)转移

有用的转移的总方案数为\(i * k + j * k + i * j\)

接着分别考虑转移到\(dp[i -1][j][k], dp[i][j - 1][k], dp[i][j][k - 1]\)的贡献。

code

#include<bits/stdc++.h>
using namespace std;
#define ld long double 
int r,s,p;
ld dp[105][105][105];
ld ans[4];
int main(){
    scanf("%d%d%d",&r,&s,&p);
    dp[r][s][p] = 1;
    for(int i = r; i >= 0; -- i)
    for(int j = s; j >= 0; -- j)
    for(int k = p; k >= 0; -- k)
    if(dp[i][j][k] > 0){
         int fm = i * j + j * k + i * k;
         if(fm == 0) continue;
         if(i) dp[i - 1][j][k] += dp[i][j][k] * i * k / fm;
         if(j) dp[i][j - 1][k] += dp[i][j][k] * j * i / fm;
         if(k) dp[i][j][k - 1] += dp[i][j][k] * k * j / fm;
    }
    for(int i = 1; i <= r; ++ i) ans[1] += dp[i][0][0];
    for(int i = 1; i <= s; ++ i) ans[2] += dp[0][i][0];
    for(int i = 1; i <= p; ++ i) ans[3] += dp[0][0][i];
    for(int i = 1; i <= 3; ++ i) printf("%.12Lf\n",ans[i]);
	return 0;
}
posted @ 2020-08-10 20:35  zhuzihan  阅读(89)  评论(0编辑  收藏  举报