Neo's Blog

不抽象就无法深入思考
不还原就看不到本来面目!

0%

骰子的点数

题目描述

将一个骰子投掷n次,获得的总点数为s,s的可能范围为n~6n。

掷出某一点数,可能有多种掷法,例如投掷2次,掷出3点,共有[1,2],[2,1]两种掷法。

请求出投掷n次,掷出n~6n点分别有多少种掷法。

样例1
输入:n=1

输出:[1, 1, 1, 1, 1, 1]

解释:投掷1次,可能出现的点数为1-6,共计6种。每种点数都只有1种掷法。所以输出[1, 1, 1, 1, 1, 1]。
样例2
输入:n=2

输出:[1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]

解释:投掷2次,可能出现的点数为2-12,共计11种。每种点数可能掷法数目分别为1,2,3,4,5,6,5,4,3,2,1。

所以输出[1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]。

思路

  1. DFS
  2. 因为有很多重复计算,所以考虑用DP来优化,状态转移方程:

表示i次骰子透出j的投法数量。

DFS代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
public:
vector<int> path;
vector<int> res;

void dfs(int n, int sum) {
if (n == 0) {
res[sum]++;
return;
}

for (int i = 1; i <= 6; ++i) {
dfs(n - 1, sum + i);
}
}

vector<int> numberOfDice(int n) {
res.resize(6 * n + 1);
dfs(n, 0);

vector<int> ret;
for (auto x : res) {
if (x > 0) ret.push_back(x);
}

return ret;
}
};
你的支持是我坚持的最大动力!