問題描述:把
n個骰子扔在地上,所有骰子朝上一面的點數之和為
s。輸入
n,列印出
s的所有可能的值出現的概率。
思路:
這是個排列問題!
這是個排列問題!
這是個排列問題!
這是一道應用動態規劃思想的題目,而動態規劃最難的就是要找最優子結構。並採取一種稱為備忘錄的方法避免重複計算。因為備忘錄方法為每個解過的子問題建立了備忘錄,以備需要時參看,避免了相同子問題的重複求解。
本題的最優子結構為:f(k, n) 表示k個骰子點數和為n的種數,
k表示骰子個數,n表示k個骰子的點數和
/ = f(k-1, n-6) + f(k-1, n-5) + f(k-1, n-4) + f(k-1, n-3) + f(k-1, n-2) + f(k-1, n-1) 對於 k > 0, k <= n <= 6*k
f(k, n) =
\ = 0 對於 n < k or n > 6*k
當k=1時, f(1,1)=f(1,2)=f(1,3)=f(1,4)=f(1,5)=f(1,6)=1。
當k= 2時,f(2,7) = f(1,1) + f(1,2) + f(1,3) + f(1,4) + f(1,5) + f(1,6)
= 6.
注意到了吧,f(2,7) = 6 (1+6,2+5,3+4,4+3,5+2,6+1),這是個排列問題!所以可以用動態規劃!
從上面公式可以看出,k個骰子點數和為n的種數只與k-1個骰子的和有關。這就可以用到備忘錄的方法,用一張**儲存已解決的子問題的解,然後自底向上填表。考慮到當前層的計算只與下一層有關,因此只需儲存一行。
參考**:
const int face_num = 6; //骰子的面數
//函式功能 : n個骰子的點數
//函式引數 : number為骰子數
//返回值 : 無
void printsumprobabilityofdices(int number)
} //不可能的情況,即i個骰子的和不可能小於i
for(j = i - 1;j >= 0; j--)
psum[j] = 0;
} //列印結果
for(i = 0; i <= size; i++)
cout<<"sum = "<
n個骰子的點數
把n個骰子扔在地上,所有骰子朝上的一面的點數之和為s。輸入n,列印出s的所有可能的值和出現的概率。1 基於迴圈求骰子點數 2int g maxvalue 6 骰子的點數個數 3void printprobability int number number 為骰子個數49 int pprobabili...
n個骰子的點數
題目 把n個骰子扔在地上,所有骰子朝上一面的點數之和為s。輸入n,列印出s的所有可能的值出現的概率。方法一 遞迴 思路 設n個骰子某次投擲點數和為s的出現次數是f n,s 那麼,f n,s 等於n 1個骰子投擲的點數和為s 1 s 2 s 3 s 4 s 5 s 6時的次數的總和 f n s f n...
n個骰子的點數
題目 把n個骰子扔在地上,所有骰子朝上一面的點數之和為s。輸入n,列印出s的所有可能的值出現的概率。方法一 遞迴 思路 設n個骰子某次投擲點數和為s的出現次數是f n,s 那麼,f n,s 等於n 1個骰子投擲的點數和為s 1 s 2 s 3 s 4 s 5 s 6時的次數的總和 f n s f n...