n个骰子的点数 java_n个骰子的点数和为s的概率集合输出(Java)
問題描述:
把n個骰子仍在地上,所有骰子朝上一面的點數之和為s,輸入n,打印出s的所有可能出現的概率
問題分析:
這是一道應用動態規劃思想的題目,而動態規劃最難的就是要找最優子結構。并采取一種稱為備忘錄的方法避免重復計算。因為備忘錄方法為每個解過的子問題建立了備忘錄,以備需要時參看,避免了相同子問題的重復求解。
最優子結構:
F(n, s) 表示n個骰子點數和為s的種數,n表示骰子個數,s表示n個骰子的點數和
F(n, s) = F(n-1, s-1) + F(n-1, s-2) + F(n-1, s-3) + F(n-1, s-4) + F(n-1, s-5) + F(n-1, s-6)
public class Probability {
public void printProbability(int number) { //number為骰子的個數
if (number < 1) return;
int g_maxValue = 6; //骰子的最大點數為6
int[][] probabilities = new int[2][]; //定義兩個數組用于保存前一循環的數據供下一階段使用
probabilities[0] = new int[g_maxValue * number + 1];
probabilities[1] = new int[g_maxValue * number + 1];
int flag = 0; //用于表示輪數交換的表示,當前階段的信息做下一階段的輸入,上一階段的信息清空,表示下階段的輸出
//初始化骰子為1時,F(1,s) 的頻數
for (int i = 1; i <= g_maxValue; i++)
probabilities[0][i] = 1;
// n表示s要加上第n個骰子朝上的數,也表示n輪大循環
for (int n = 2; n <= number; ++n) {
// 歸零操作,因為隨著s的變大,F(1,0), F(2,1), F(3,2),...,F(6,5)都不會出現,但是前面計算出現過F(1,1), F(2,2), F(3,3),...,F(5,5),
//因為我們是交替使用前一個數組,所以必須作歸零處理
for (int i = 0; i < n; ++i)
probabilities[1 - flag][i] = 0;
//第n輪數據之和為s∈[n, g_maxValue*n],然后計算每一個s的頻數
for (int s = n; s <= g_maxValue * n; ++s) {
probabilities[1 - flag][s] = 0; // 第n輪第n個數據初始化為0
//計算F(n, s) = F(n-1, s-1) + F(n-1, s-2) + F(n-1, s-3) + F(n-1, s-4) + F(n-1, s-5) + F(n-1, s-6)
for (int j = 1; j <= s && j <= g_maxValue; ++j)
probabilities[1 - flag][s] += probabilities[flag][s - j];
}
flag = 1 - flag;
}
double total = Math.pow(g_maxValue, number);
for (int i = number; i <= g_maxValue * number; i++) {
double ratio = (double) probabilities[flag][i] / total;
System.out.println(i);
System.out.println(ratio);
}
}
}
總結
以上是生活随笔為你收集整理的n个骰子的点数 java_n个骰子的点数和为s的概率集合输出(Java)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: arccatalog点要素显示不完,sh
- 下一篇: verilog异步复位jk触发器_HDL