CodeForces 540D--概率dp

来源:互联网 发布:ubuntu 启动过程 黑屏 编辑:程序博客网 时间:2024/06/05 00:04

题意:

在一个岛上,有 r 个石头,s 个剪刀和 p 个布,遵循石头剪刀布的规则,他们之间相遇的概率相等,问他们存活的概率。


输入:

2 2 2
2 1 2
1 1 3

输出:

0.333333333333 0.333333333333 0.333333333333
0.150000000000 0.300000000000 0.550000000000
0.057142857143 0.657142857143 0.285714285714

分析:

用一个三维dp来表示岛上存活r,s,p的概率。初始dp[r][s][p]=1,转移:总共情况tol = i*j+i*k+j*k .

转移:

dp[i-1][j][k] += dp[i][j][k]*(i*k*1.0/sum);
dp[i][j-1][k] += dp[i][j][k]*(j*i*1.0/sum);
dp[i][j][k-1] += dp[i][j][k]*(j*k*1.0/sum);

最后留下两个物种在岛上时,就能确定谁能存活了,因为两者是相克的。最后在统一算就好。


代码:


三维dp

<span style="font-family: SimSun;"><span style="font-size:14px;">#include <bits/stdc++.h>using namespace std;const int maxn=105;double dp[maxn][maxn][maxn];int main(){    int r,s,p;    cin >>r>>s>>p;    dp[r][s][p]=1.0; //初始状态1    for(int i=r; i>=1; i--)    {        for(int j=s; j>=1; j--)        {            for(int k=p; k>=1; k--)            {                double sum=i*j+i*k+j*k; //总情况                dp[i-1][j][k] += dp[i][j][k]*(i*k*1.0/sum);                dp[i][j-1][k] += dp[i][j][k]*(j*i*1.0/sum);                dp[i][j][k-1] += dp[i][j][k]*(j*k*1.0/sum);            }        }    }    double ans1=0.0,ans2=0.0,ans3=0.0;    for(int i=1; i<=100; i++)    {        for(int j=0; j<=100; 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;}</span></span>

0 0
原创粉丝点击