CodeForces 540D Bad Luck Island (DP)

题意:一个岛上有石头,剪刀和布,规则就不用说了,问你最后只剩下每一种的概率是多少。

析:很明显的一个概率DP,用d[i][j][k]表示,石头剩下 i 个,剪刀剩下 j 个,布剩下 k 个,d[r][s][p] = 1,那状态转发方程怎么写呢?是这样的

如果石头减少了1,那么肯定是布干的,那么是哪个布干掉了哪个石头呢?这又是另一个问题,答案就是 i * k,那么总数就是 i * k + i * j + j * k。

最后再把各项加起来即可。

代码如下:

#include <iostream>
#include <cstdio>

using namespace std;
const int maxn = 100 + 5;
double d[maxn][maxn][maxn];

int main(){
    int r, p, s;
    cin >> r >> s >> p;
    d[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 && !j && !k)  continue;
                double sum = i * j + i * k + k * j;
                if(!sum)   continue;
                if(i && k)  d[i-1][j][k] += d[i][j][k] * i * k / sum;
                if(i && j)  d[i][j-1][k] += d[i][j][k] * i * j / sum;
                if(j && k)  d[i][j][k-1] += d[i][j][k] * j * k / sum;
            }
        }
    }

    double ansr = 0, ansp = 0, anss = 0;
    for(int i = 1; i <= r; ++i)  ansr += d[i][0][0];
    for(int i = 1; i <= s; ++i)  anss += d[0][i][0];
    for(int i = 1; i <= p; ++i)  ansp += d[0][0][i];
    printf("%.12lf %.12lf %.12lf
", ansr, anss, ansp);
    return 0;
}
原文地址:https://www.cnblogs.com/dwtfukgv/p/5706470.html