n個骰子個點數和出現的概率- 動態規劃
阿新 • • 發佈:2019-02-13
題目:把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; }