837.New 21 Game === ###### tags: `Medium`,`Math`,`DP`,`Sliding Window` [837. New 21 Game](https://leetcode.com/problems/new-21-game/) ### 題目描述 Alice plays the following game, loosely based on the card game **"21"**. Alice starts with `0` points and draws numbers while she has less than `k` points. During each draw, she gains an integer number of points randomly from the range `[1, maxPts]`, where `maxPts` is an integer. Each draw is independent and the outcomes have equal probabilities. Alice stops drawing numbers when she gets `k` **or more points**. Return the probability that Alice has `n` or fewer points. Answers within 10^-5^ of the actual answer are considered accepted. ### 範例 **Example 1:** ``` Input: n = 10, k = 1, maxPts = 10 Output: 1.00000 Explanation: Alice gets a single card, then stops. ``` **Example 2:** ``` Input: n = 6, k = 1, maxPts = 10 Output: 0.60000 Explanation: Alice gets a single card, then stops. In 6 out of 10 possibilities, she is at or below 6 points. ``` **Example 3:** ``` Input: n = 21, k = 17, maxPts = 10 Output: 0.73278 ``` **Constraints**: * 0 <= `k` <= `n` <= 10^4^ * 1 <= `maxPts` <= 10^4^ ### 解答 #### Python ```python= class Solution: def new21Game(self, n: int, k: int, maxPts: int) -> float: if k == 0 or n >= k - 1 + maxPts: return 1.0 dp = [0.0] * (n + 1) dp[0] = 1.0 prob, total = 0.0, 1.0 for i in range(1, n + 1): dp[i] = total / maxPts if i < k: total += dp[i] else: prob += dp[i] if i >= maxPts: total -= dp[i - maxPts] return prob ``` > [name=Yen-Chi Chen][time=Thu, May 25, 2023] #### C++ ``` cpp= class Solution { public: double new21Game(int targetPoint, int stopPoint, int maxPointPerDraw) { ios_base::sync_with_stdio(0); cin.tie(0); double ans = 0.; if (stopPoint == 0 or targetPoint >= stopPoint + maxPointPerDraw) { return 1.; } vector<double> probability(targetPoint + 1, 0); probability[0] = 1.; double slideWindowSum = 1.; for (int possiblePoint = 1; possiblePoint <= targetPoint; possiblePoint ++) { probability[possiblePoint] = slideWindowSum / maxPointPerDraw; if (possiblePoint < stopPoint) { slideWindowSum += probability[possiblePoint]; } else { ans += probability[possiblePoint]; } if (possiblePoint - maxPointPerDraw >= 0) { slideWindowSum -= probability[possiblePoint - maxPointPerDraw]; } } return ans; } }; ``` > [name=Jerry Wu][time=Thu, May 25, 2023] ### Reference [回到題目列表](https://hackmd.io/@Marsgoat/leetcode_every_day)