[DP] $のP2059 $確率カードゲーム

[DP]確率\(P2059 \)カードゲーム

リンク

タイトル説明

\(N \)個人がゲームをプレイサークルに座っています。まずはから時計回りに、すべてのプレーヤーを置く\(1 \)する(N \)\数を。最初のラウンドは、第1選手です\(1 \)ディーラーとして。各ラウンドは、カードの山からカードを選択する(つまり、同じ確率で、ある)ランダム作るためのカードの数字と仮定されます\(X- \)は、すべてのプレイヤーに見せるためにカード上の最初の番号を作り、を押し数のディーラー位置から時計回りに\(X \)個人がゲームを終了するために実行されます。その後、カードはカードや改造の山に戻されます。時計回りにディーラーの次のラウンドとなる次の人によって実行された方。そして、後に(N-1 \)\最後のラウンドの後は一人だけを残して、このゲームは勝者です。今、あなたが事前に知っている合計\(M \)カードは、各カードにその番号を知っています。今、あなたは、各プレイヤーの勝利の確率を決定する必要があります。

入力形式

最初の行は二つの整数含む\(N、M \)をそれぞれ表す数と選手カードの総数。

次の行を含む\(M \)整数は、それぞれのカードに書かれた番号を与えます。

出力フォーマット

含む出力ライン(N \)\小数点以下に与えられたパーセント数の形で固体。プレイヤーは別に与えられた\(1 \)プレイヤーに\(N \)の勝利確率、スペースで区切ってそれぞれの間の確率、そして最後にスペースなし。

サンプル ]

5 5
2 3 5 7 11
22.72% 17.12% 15.36% 25.44% 19.36%
4 4
3 4 5 6
25.00% 25.00% 25.00% 25.00%

以下のために(30 \)\データの%、ある(1 \当量のNの\の当量\ 10 \)は

以下のために(50 \)\データの%、ある(1 \当量のNの\の当量\ 30 \)は

以下のために(100 \)\データの%、ある\(1 \当量N \の当量 50、1 \当量M \の当量50、1 \当量の\) 各カードの数字(\ \当量50 \)

\(溶液\)

実際には、この質問は、私はすべてのことを考え始めました。考え始め、検索ですが、それはたくさんのことを記録しているようだ、私は転送が実行可能ではないと思いました。それは......後方検索しますか?

セット([I] [J F \ ] \) 持っている\(私は\)個々の時間、\(j個\)個人的な勝利の確率。確率を加えることができるので、それは押し戻さすることができます。

どのように転送するには?手は、それがことがわかった(私は\)\描かれたディーラーのカードは、個人の場合には\(k個\) そして- \(1 \ⅰ)個人的な最初の\(J \)個人的な位置である......カテゴリー話。もし<\(K J \)、\ - (K \ J = J) もし(J \ \ K)>、\ (J = I - K + J \) あれば\(K = J \) しませんので、考える\(jは\)が死亡しました。

だから、長い間遷移方程式:

int p = a[k] % i == 0? i:a[k] % i;
if(p > j) f[i][j] += f[i - 1][i - p + j] / m;
else if(p < j) f[i][j] += f[i - 1][j - p] / m;

\(それは\ ~~すべてです)

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
long long read(){
    long long x = 0; int f = 0; char c = getchar();
    while(c < '0' || c > '9') f |= c == '-', c = getchar();
    while(c >= '0' && c <= '9') x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
    return f? -x:x;
}

int n, m, a[57];
double f[57][57];
int main(){
    n = read(); m = read();
    for(int i = 1; i <= m; ++i) a[i] = read();
    f[1][1] = 1.0;
    for(int i = 2; i <= n; ++i)
        for(int j = 1; j <= i; ++j)
            for(int k = 1; k <= m; ++k){
                int p = a[k] % i == 0? i:a[k] % i;
                if(p > j) f[i][j] += f[i - 1][i - p + j] / m;
                else if(p < j) f[i][j] += f[i - 1][j - p] / m;
            }
    printf("%.2lf%%", f[n][1] * 100);
    for(int i = 2; i <= n; ++i) printf(" %.2lf%%", f[n][i] * 100);
    return 0;
}

おすすめ

転載: www.cnblogs.com/kylinbalck/p/11260150.html