CodeForces 540D--Bad Luck Island(概率DP)

貌似竟然是我的第一道概率DP。。

手机码代码真不舒服。。。。

/************************************************
Memory: 67248 KB		Time: 31 MS
Language: GNU G++ 4.9.2		Result: Accepted
************************************************/
/**
一个岛上住着一些石头,剪刀,布,他们互相之间两两随机碰面,如果不是一个种族,一个会杀死另一个
最后只会活下一个种族,求最后活下来的是各个种族的概率

这tm原来是一道概率dp,那我也不会啊 =。=
想一想。。。dp[i][j][k] 表示三个种族分别剩下i,j,k的概率
那么初始dp[a][b][c] = 1;
a和b碰面的概率是i*j/i*j+j*k+k*i,所以死一只b的概率是i*j/i*j+j*k+k*i(如果不是看别人题解,我绝对想不到啊啊,概率渣)
那么由dp[i][j][k]到dp[i][j-1][k]的概率是i*j/i*j+j*k+k*i
对于dp[i][j][k]来说,有三种情况可以到达它,dp[i+1][j][k],dp[i][j+1][k],dp[i][j][k+1]
所以dp[i][j][k]=dp[i+1][j][k] * k*(i+1) / ((i+1)*j + j*k + k*(i+1)) +
                dp[i][j+1][k] * i*(j+1) / (i*(j+1) + k*i + (j+1)*k) +
                dp[i][j][k+1] * j*(k+1) / (j*(k+1) + j*i + (k+1)*i)
还有一点问题就是。。当i,j,k中有两个为0的时候,表达式会出现分母为0的情况
考虑到其实dp[i][0][0]已经不能再转移了,所以判断一下
*/
#include<stdio.h>
double dp[205][205][205];
int main()
{
    int a, b, c;
    scanf("%d%d%d", &a, &b, &c);
    dp[a][b][c] = 1;
    for (int i = a; i >= 0; --i)
    {
        for (int j = b; j >= 0; --j)
        {
            for (int k = c; k >= 0; --k)
            {
                if (i == a && j == b && k == c) continue;
                if (j || k)
                    dp[i][j][k] += dp[i + 1][j][k] * k * (i + 1) / (k * (i + 1) + j * k + (i + 1) * j);
                if (i || k)
                    dp[i][j][k] += dp[i][j + 1][k] * i * (j + 1) / (i * (j + 1) + (j + 1) * k + i * k);
                if (i || j)
                    dp[i][j][k] += dp[i][j][k + 1] * j * (k + 1) / (j * (k + 1) + j * i + (k + 1) * i);
                //printf("dp[%d][%d][%d]=%f
", i, j, k, dp[i][j][k]);
            }
        }
    }
    double p1, p2, p3;
    p1 = p2 = p3 = 0;
    for (int i = 1; i <= a; ++i)
        p1 += dp[i][0][0];
    for (int i = 1; i <= b; ++i)
        p2 += dp[0][i][0];
    for (int i = 1; i <= c; ++i)
        p3 += dp[0][0][i];
    printf("%.9f %.9f %.9f", p1, p2, p3);
    return 0;
}

  

原文地址:https://www.cnblogs.com/wenruo/p/4920134.html