Codeforces B.不運島(確率DP)

件名の説明:

不運島

テストあたりの時間制限

2秒

テストごとのメモリ制限

256メガバイト

入力

標準入力

出力

標準出力

:不運島は、種の3種類が生息しているR岩、sのはさみとのp論文。2人のランダム個人が会う時間のいくつかの瞬間に(個人のすべてのペアがequiprobably満たすことができます)、およびそれらが異なる種に属する場合には、一人の個人は、他の1を殺す:岩ははさみは、ハサミが紙を殺す殺し、そして紙は岩を殺します。あなたの仕事は、この種は、時間の十分に長い期間の後、この島に生息する唯一の1になる確率が何であるかをそれぞれの種のために決定することです。

入力

単一の行は三つの整数含まrはSおよびP(1≤  R、  S、  P  ロック、はさみ、紙の種における個体の元の数、それぞれ- 100≤)を。

出力

確率で石、ハサミと紙はそれぞれ、現存する唯一の種になります:3スペースで区切られた実数を印刷します。9 - 各数値の相対的または絶対誤差が10を超えない場合答えが正しいとみなされます。

入力

コピー

2 2 2

出力

コピー

0.333333333333 0.333333333333 0.333333333333

入力

コピー

2 1 2

出力

コピー

0.150000000000 0.300000000000 0.550000000000

入力

コピー

1 1 3

出力

コピー

0.057142857143 0.657142857143 0.285714285714

アイデア:

この質問は、単に時間を見て、ああ良い魔法を感じ、背の高い良い確率に知識を使用してください、私の数学はそれだけスキップすることができ、オーバー失われている。さ あなたは、より良い法律が魔法のような感じ、ああ〜魔法の確率DPを理解わかったら。

DP [I] [J] [k]の定義は、ロックは、j番目の残りのはさみは、確率k番目布左起こる残りi番目の種です。DP開始[R] [S] [P] = 1、今の状態遷移を考えます。

ときハサミはそれより少ないでしょうか?これは、この出来事の確率はそれで、石に遭遇しましたか?(\ \ {C_S FRAC * C_R ^^。1. 1} + {R&LT C_ {P} S ^ 2} + \) 少なくとも一つの織物同様それ?それは、それの確率をハサミに遭遇しましたか?\(\ FRAC {C_P ^ 1 * ^ 1 C_S} {C_ {R&LT + S + P} ^ 2} \)、少なくとも一つの確率石\(\ FRAC {C_P ^ 1 * C_R ^ 1}、{C_ { } S + P + R&LT ^ 2} \) 次いで、状態遷移式であります

\ [合計=源Q +明確な\ +]

\ [DP [I-1]〜[J] [K] + = DP [I] [J] [K] * \ FRAC {C_S ^ 1 * C_R ^ 1} {和} \]

\ [DP [I]、[J-1] [K] + = DP [I] [J] [K] * \ FRAC {C_P ^ 1 * C_R ^ 1}、{C_ {和} ^ 2} \]

\ [DP [I] [J] [K-1] + = DP [I] [J] [K] * \ FRAC {C_P ^ 1 * C_S ^ 1}、{C_ {和} ^ 2} \]

再帰は、ゼロからスタートします。

統計最後の回答の統計DP [I] [J]この結果に対する答えは設定されているので、[0]この答えを、一つだけの種があります

コード:

#include <iostream>
#include <iomanip>
#define max_n 105
using namespace std;
int r,s,p;
double dp[max_n][max_n][max_n];
int main()
{
    cin >> r >> s >> p;
    dp[r][s][p] = 1.0;
    for(int i = r;i>0;i--)
    {
        for(int j = s;j>0;j--)
        {
            for(int k = p;k>0;k--)
            {
                double sum = i*j+i*k+j*k;
                dp[i-1][j][k] += dp[i][j][k]*(double)(i*k)/sum;
                dp[i][j-1][k] += dp[i][j][k]*(double)(i*j)/sum;
                dp[i][j][k-1] += dp[i][j][k]*(double)(j*k)/sum;
            }
        }
    }
    double ans1 = 0;
    double ans2 = 0;
    double ans3 = 0;
    for(int i = 0;i<=100;i++)
    {
        for(int j = 0;j<=100;j++)
        {
            ans1 += dp[i][j][0];
            ans2 += dp[0][i][j];
            ans3 += dp[i][0][j];
        }
    }
    cout.setf(ios_base::fixed,ios_base::floatfield);
    cout << setprecision(12) << ans1 << " " << ans2 << " " << ans3 << endl;
    return 0;
}

おすすめ

転載: www.cnblogs.com/zhanhonhao/p/11332955.html