|
69 | 69 | * [58.1 翻转单词顺序列](#581-翻转单词顺序列)
|
70 | 70 | * [58.2 左旋转字符串](#582-左旋转字符串)
|
71 | 71 | * [59. 滑动窗口的最大值](#59-滑动窗口的最大值)
|
| 72 | +* [60. n 个骰子的点数](#60-n-个骰子的点数) |
72 | 73 | * [61. 扑克牌顺子](#61-扑克牌顺子)
|
73 | 74 | * [62. 圆圈中最后剩下的数](#62-圆圈中最后剩下的数)
|
74 | 75 | * [63. 股票的最大利润](#63-股票的最大利润)
|
@@ -1764,6 +1765,65 @@ public ArrayList<Integer> maxInWindows(int[] num, int size) {
|
1764 | 1765 | }
|
1765 | 1766 | ```
|
1766 | 1767 |
|
| 1768 | +# 60. n 个骰子的点数 |
| 1769 | + |
| 1770 | +**题目描述** |
| 1771 | + |
| 1772 | +把 n 个骰子仍在地上,求点数和为 s 的概率。 |
| 1773 | + |
| 1774 | +最直观的动态规划解法,O(n<sup>2</sup>) 的空间复杂度。 |
| 1775 | + |
| 1776 | +```java |
| 1777 | +private static int face = 6; |
| 1778 | + |
| 1779 | +public double countProbability(int n, int s) { |
| 1780 | + if (n < 1 || s < n) return 0.0; |
| 1781 | + int pointNum = face * n; |
| 1782 | + int[][] dp = new int[n][pointNum]; |
| 1783 | + for (int i = 0; i < face; i++) { |
| 1784 | + dp[0][i] = 1; |
| 1785 | + } |
| 1786 | + for (int i = 1; i < n; i++) { |
| 1787 | + for (int j = i; j < pointNum; j++) { // 使用 i 个骰子最小点数为 i |
| 1788 | + for (int k = 1; k <= face; k++) { |
| 1789 | + if (j - k < 0) continue; |
| 1790 | + dp[i][j] += dp[i - 1][j - k]; |
| 1791 | + } |
| 1792 | + } |
| 1793 | + } |
| 1794 | + |
| 1795 | + int totalNum = (int) Math.pow(6, n); |
| 1796 | + return (double)dp[n - 1][s - 1] / totalNum; |
| 1797 | +} |
| 1798 | +``` |
| 1799 | + |
| 1800 | +使用旋转数组将空间复杂度降低为 O(n) |
| 1801 | + |
| 1802 | +```java |
| 1803 | +private static int face = 6; |
| 1804 | + |
| 1805 | +public double countProbability(int n, int s) { |
| 1806 | + if (n < 1 || s < n) return 0.0; |
| 1807 | + int pointNum = face * n; |
| 1808 | + int[][] dp = new int[2][pointNum]; |
| 1809 | + for (int i = 0; i < face; i++) { |
| 1810 | + dp[0][i] = 1; |
| 1811 | + } |
| 1812 | + int flag = 1; |
| 1813 | + for (int i = 1; i < n; i++) { |
| 1814 | + for (int j = i; j < pointNum; j++) { // 使用 i 个骰子最小点数为 i |
| 1815 | + for (int k = 1; k <= face; k++) { |
| 1816 | + if (j - k < 0) continue; |
| 1817 | + dp[flag][j] += dp[1 - flag][j - k]; |
| 1818 | + } |
| 1819 | + } |
| 1820 | + } |
| 1821 | + |
| 1822 | + int totalNum = (int) Math.pow(6, n); |
| 1823 | + return (double) dp[n - 1][s - 1] / totalNum; |
| 1824 | +} |
| 1825 | +``` |
| 1826 | + |
1767 | 1827 | ## 61. 扑克牌顺子
|
1768 | 1828 |
|
1769 | 1829 | **题目描述**
|
|
0 commit comments