codeforces 540D
题意:
指
定
r
个
人
出
石
头
,
s
个
人
出
剪
刀
,
p
个
人
出
布
。
指定r个人出石头,s个人出剪刀,p个人出布。
指定r个人出石头,s个人出剪刀,p个人出布。
每
隔
一
段
时
间
两
两
相
遇
,
按
照
剪
刀
石
头
布
的
规
则
,
可
能
会
有
一
人
淘
汰
出
局
。
每隔一段时间两两相遇,按照剪刀石头布的规则,可能会有一人淘汰出局。
每隔一段时间两两相遇,按照剪刀石头布的规则,可能会有一人淘汰出局。
问
最
终
三
个
阵
营
获
胜
的
概
率
。
问最终三个阵营获胜的概率。
问最终三个阵营获胜的概率。
题解:
d p [ i ] [ j ] [ k ] 表 示 石 头 还 剩 下 i 人 , 剪 刀 还 剩 下 j 人 , 布 还 剩 下 k 人 的 概 率 。 dp[i][j][k]表示石头还剩下i人,剪刀还剩下j人,布还剩下k人的概率。 dp[i][j][k]表示石头还剩下i人,剪刀还剩下j人,布还剩下k人的概率。
- 石 头 和 布 相 遇 , d p [ i − 1 ] [ j ] [ k ] + = d p [ i ] [ j ] [ k ] ∗ i ∗ k i ∗ j + j ∗ k + k ∗ i 石头和布相遇,dp[i-1][j][k] += dp[i][j][k]*\frac {i*k}{i*j+j*k+k*i} 石头和布相遇,dp[i−1][j][k]+=dp[i][j][k]∗i∗j+j∗k+k∗ii∗k
- 石 头 和 剪 刀 相 遇 , d p [ i ] [ j − 1 ] [ k ] + = d p [ i ] [ j ] [ k ] ∗ i ∗ j i ∗ j + j ∗ k + k ∗ i 石头和剪刀相遇,dp[i][j-1][k] += dp[i][j][k]*\frac {i*j}{i*j+j*k+k*i} 石头和剪刀相遇,dp[i][j−1][k]+=dp[i][j][k]∗i∗j+j∗k+k∗ii∗j
- 剪 刀 和 布 相 遇 , d p [ i ] [ j ] [ k − 1 ] + = d p [ i ] [ j ] [ k ] ∗ j ∗ k i ∗ j + j ∗ k + k ∗ i 剪刀和布相遇,dp[i][j][k-1] += dp[i][j][k]*\frac {j*k}{i*j+j*k+k*i} 剪刀和布相遇,dp[i][j][k−1]+=dp[i][j][k]∗i∗j+j∗k+k∗ij∗k
#include <bits\stdc++.h>
using namespace std;
const int N = 101;
double dp[N][N][N];
double getP(int a, int b, int c){
if(a*b+b*c+c*a == 0){
return 0;
}
return (a*b)*1.0/(a*b+b*c+c*a)*1.0;
}
int main() {
int r, s, p;
cin >> 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(i >= 1){
dp[i-1][j][k] += dp[i][j][k]*getP(i, k, j);
}
if(j >= 1){
dp[i][j-1][k] += dp[i][j][k]*getP(i, j, k);
}
if(k >= 1){
dp[i][j][k-1] += dp[i][j][k]*getP(j, k, i);
}
}
}
}
double pr = 0, ps = 0, pp = 0;
for(int i = 0 ; i <= r ; i++){
pr += dp[i][0][0];
}
for(int i = 0 ; i <= s ; i++){
ps += dp[0][i][0];
}
for(int i = 0 ; i <= p ; i++){
pp += dp[0][0][i];
}
cout << setiosflags(ios::fixed) << setprecision(9) << pr << ' ' << ps << ' ' << pp << endl;
return 0;
}