トップページに戻る    次の競技プログラミングの問題へ    前の競技プログラミングの問題へ

No.567 コンプリート

■■■問題■■■

6面のサイコロをn回投げます。サイコロの目が全て出る確率を求めて下さい。

■■■入力■■■

N

●1 <= N <= 100万

■■■出力■■■

n回投げて全ての面が出る確率を出力してください
絶対誤差または相対誤差が10の-7乗以下なら許容されます。


C#のソース

using System;
using System.Collections.Generic;

class Program
{
    static string InputPattern = "InputX";

    static List<string> GetInputList()
    {
        var WillReturn = new List<string>();

        if (InputPattern == "Input1") {
            WillReturn.Add("1");
            //0
            //1回投げて全部揃うことはありません
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("6");
            //0.015432098765432
            //(1/6)の6乗 * 6の階乗
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("7");
            //0.054012345
        }
        else if (InputPattern == "Input4") {
            WillReturn.Add("50");
            //0.99934071
            //このくらいになるとほぼ確実に全て出ますね
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    static void Main()
    {
        List<string> InputList = GetInputList();
        int N = int.Parse(InputList[0]);

        //確率[登場した目の数]なDP表
        double[] PrevDP = new double[7];
        PrevDP[0] = 1D;

        for (int I = 1; I <= N; I++) {
            double[] CurrDP = new double[7];

            for (int J = 0; J <= 6; J++) {
                //登場した目の数が増えない確率
                double HuenaiP = J / 6D;
                CurrDP[J] += PrevDP[J] * HuenaiP;

                //登場した目の数が1増える確率
                double HueruP = 1D - HuenaiP;

                if (J <= 5) {
                    CurrDP[J + 1] += PrevDP[J] * HueruP;
                }
            }
            PrevDP = CurrDP;
        }
        Console.WriteLine(PrevDP[6]);
    }
}


解説

登場した目の数が0個の状態でサイコロを振ると
6/6の確率で、登場した目の数が1個になります。

登場した目の数が1個の状態でサイコロを振ると
5/6の確率で、登場した目の数が2個になります。

登場した目の数が2個の状態でサイコロを振ると
4/6の確率で、登場した目の数が3個になります。

登場した目の数が3個の状態でサイコロを振ると
3/6の確率で、登場した目の数が4個になります。

登場した目の数が4個の状態でサイコロを振ると
2/6の確率で、登場した目の数が5個になります。

登場した目の数が5個の状態でサイコロを振ると
1/6の確率で、登場した目の数が6個になります。

以上をふまえて、動的計画法で解いてます。