1. 程式人生 > >n個骰子個點數和出現的概率- 動態規劃

n個骰子個點數和出現的概率- 動態規劃

題目:把n個骰子扔在地上,所有骰子朝上一面的點數之和為S。輸入n,打印出S的所有可能的值出現的概率。

宣告思想非原創!只因動態規劃思想的使用很好,記下!

分析:動態規劃就是分階段考慮問題,給出變數,找出相鄰階段間的關係。具體定義給忘了。

1.現在變數有:骰子個數,點數和。當有k個骰子,點數和為n時,出現次數記為f(k,n)。那與k-1個骰子階段之間的關係是怎樣的?

2.當我有k-1個骰子時,再增加一個骰子,這個骰子的點數只可能為1、2、3、4、5或6。那k個骰子得到點數和為n的情況有:

(k-1,n-1):第k個骰子投了點數1

(k-1,n-2):第k個骰子投了點數2

(k-1,n-3):第k個骰子投了點數3

....

(k-1,n-6):第k個骰子投了點數6

在k-1個骰子的基礎上,再增加一個骰子出現點數和為n的結果只有這6種情況!

所以:f(k,n)=f(k-1,n-1)+f(k-1,n-2)+f(k-1,n-3)+f(k-1,n-4)+f(k-1,n-5)+f(k-1,n-6)

3.有1個骰子,f(1,1)=f(1,2)=f(1,3)=f(1,4)=f(1,5)=f(1,6)=1。

int findSum(int n)
{
        // alloc 2-d array to store result,
        // the index of array is the sum,
        // the element value is times of the sum,
        // for example, if there are two dices, the array is like below'
        //         0  1  2  3  4  5  6  7  8  9  10  11  12 ...
        //a[1][] : 0  1  1  1  1  1  1                             // there is only one dice
        //a[2][] : 0  0   1  2  3  4  5  6  5  4  3   2   1         // there are two dices

        int *array[n + 1];

        //alloc array
        int j = 0;
        int i = 0;
        for (i = 0; i <= n; i++) {
                array[i] = new int[6*i + 1];
        }

        // initialise the array
        for (i = 0; i <= n; i++) {
                for (j = 0; j <= 6*i; j++) {
                        array[i][j] = 0;
                }
        }

        //calculate
        for (i = 1; i <= n; i++) {
                for (j = i; j <= 6*i; j++) {
                        if (i == 1 || j == i || j == 6*i) {
                                array[i][j] = 1;
                        } else {
                                int k;
                                for (k = 1; k <=6; k++) {
                                        if ((j-k) >= (i -1) && (j-k) <= 6*(i-1))
                                                array[i][j] += array[i-1][j-k];
                                }
                        }
                }
        }

        for (i = 1; i<= n; i++) {
                cout << "a[" << i <<"]: ";
                for (j = i; j <= 6*i; j++) {
                        cout << array[i][j] << " ";
                }
                cout<<endl;
        }

        return 0;
}