n个骰子的点数
问题简述
把 n 个骰子扔在地上,所有骰子朝上一面的点数之和为 s。
输入 n,打印出 s 的所有可能的值出现的概率(按 s 从小到大排列)。
思路1:从暴力递归到动态规划
定义
dfs(k)
返回 k 个骰子产生的可能性序列dp
,其中dp[i]
表示 k 个骰子掷出点数 i 的可能数;【递归基】
k=1
时,dfs(1)
返回dp = [_, 1, 1, 1, 1, 1, 1]
(为方便编码,dp[:n]
为占位符,无实际意义)递归过程即使用
dfs(k-1)
返回的dp_pre
生成dfs(k)
的dp
;然后根据暴力递归过程直接写出动态规划的代码(已经与原问题解耦);
思路2:从“跳台阶”理解本题
“跳台阶”的递推公式为:
dp[i] = dp[i-1] + dp[i-2]
;在本题中,可以看做目标台阶数为
i
,每次可以跳1~6
步;对k
个骰子,i
的范围为k ~ 6*k
,每次都是从n-1
个骰子的可能性出发;因此本题的递推公式为:
dp[k][i] = dp[k-1][i-1] + dp[k-1][i-2] + .. + dp[k-1][i-6]
;同时因为每一轮只和上一轮相关,可以使用两个数组滚动优化空间;
也可以只是用一个数组,参考:n个骰子的点数 - 路漫漫我不畏
代码同上。
Last updated