题目意思,剪刀,石头,布生活在一起,但是剪刀遇见石头石头会死掉,石头遇见布布会死掉,布遇见剪刀剪刀会死掉。给出你r,s,p分别代表剪刀、石头、布的数量。分别求剪刀石头布存在的概率。


设dp[i][j][k]为目前还剩下i个石头,j个剪刀,k个布。此时存活的概率都是1。如果其中一种已经消失,那么剩下两个物种便可以肯定谁会存活。

然后循环状态转移:

double tot=i*j+j*k+k*i;

dp[i-1][j][k]+=(1.0*i*k)/tot*dp[i][j][k];        //剪刀遇见石头石头会死掉

dp[i][j-1][k]+=(1.0*i*j)/tot*dp[i][j][k];        //石头遇见布布会死掉

dp[i][j][k-1]+=(1.0*j*k)/tot*dp[i][j][k];        //布遇见剪刀剪刀会死掉


之后求一个物种必定存在,第三者物种消失,将第二个物种循环求和就行。


代码:

StatusAccepted
Time30ms
Memory11116kB
Length949
LangGNU G++ 5.1.0
#include <iostream>
#include <cstdio>
#include <memory.h>
using namespace std;
const int maxn=105;
double dp[maxn][maxn][maxn];
int r, s, p;
int main()
{
    while(~scanf("%d%d%d", &r, &s, &p)){
        memset(dp, 0, sizeof(dp));
        dp[r][s][p]=1;
        for(int i=r;i>=1;i--){
            for(int j=s;j>=1;j--){
                for(int k=p;k>=1;k--){
                    double tot=i*j+j*k+k*i;
                    dp[i-1][j][k]+=(1.0*i*k)/tot*dp[i][j][k];
                    dp[i][j-1][k]+=(1.0*i*j)/tot*dp[i][j][k];
                    dp[i][j][k-1]+=(1.0*j*k)/tot*dp[i][j][k];
                }
            }
        }
        double ans1=0, ans2=0, ans3=0;
        for(int i=1;i<maxn;i++){
            for(int j=0;j<maxn;j++){
                ans1+=dp[i][j][0];
                ans2+=dp[0][i][j];
                ans3+=dp[j][0][i];
            }
        }
        printf("%.10f %.10f %.10f\n", ans1, ans2, ans3);
    }
    return 0;
}