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 kor 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 <= 104
1 <= maxPts <= 104
Solutions
Solution 1: Memoized Search
Thinking
We add a uniform integer in \([1,\textit{maxPts}]\) until the total reaches \(k\), and want the probability it is still \(\le n\). Expanding every draw is impossible for \(k,n\le 10^4\); memoize on the current total.
\(\textit{dfs}(i)\) is the success probability from total \(i\). For \(i\ge k\) we stop and test \(i\le n\); \(i=k-1\) has a closed form. Other states use a difference of neighbors so each transition is \(O(1)\) instead of \(O(\textit{maxPts})\).
We design a function \(\textit{dfs}(i)\), which represents the probability that when the current score is \(i\), the final score does not exceed \(n\) when we stop drawing numbers. The answer is \(\textit{dfs}(0)\).
The calculation method of function \(\textit{dfs}(i)\) is as follows:
If \(i \ge k\), then we stop drawing numbers. If \(i \le n\), return \(1\), otherwise return \(0\);
Otherwise, we can draw the next number \(j\) in the range \([1,..\textit{maxPts}]\), then \(\textit{dfs}(i) = \frac{1}{\textit{maxPts}} \sum_{j=1}^{\textit{maxPts}} \textit{dfs}(i+j)\).
Here we can use memoized search to accelerate the calculation.
The time complexity of the above method is \(O(k \textit{maxPts})\), which will exceed the time limit, so we need to optimize it.
We assume there are \(i\) numbers not exceeding \(n\), then \(k+i-1 \leq n\), and since \(i\leq \textit{maxPts}\), we have \(i \leq \min(n-k+1, \textit{maxPts})\), so equation \((3)\) can be written as:
Solution 1 already fills the probabilities from the high scores downward. Each \(f[i]\) comes from \(f[i+1]\) and the window end \(f[i+\textit{maxPts}+1]\).
Terminals in \([k,\min(n,k+\textit{maxPts}))\) are \(1\). The answer is \(f[0]\). Time stays linear.
Solution 1 already fills this table from the high scores downward. The transitions below are the same ones.
Define \(f[i]\) to represent the probability that when the current score is \(i\), the final score does not exceed \(n\) when we stop drawing numbers. The answer is \(f[0]\).
When \(k \leq i \leq \min(n, k + \textit{maxPts} - 1)\), we have \(f[i] = 1\).
When \(i = k - 1\), we have \(f[i] = \min(n-k+1, \textit{maxPts}) / \textit{maxPts}\).
When \(i \lt k - 1\), we have \(f[i] = f[i + 1] + (f[i + 1] - f[i + \textit{maxPts} + 1]) / \textit{maxPts}\).
The time complexity is \(O(k + \textit{maxPts})\), and the space complexity is \(O(k + \textit{maxPts})\), where \(k\) is the maximum score.
We add a uniform integer in \([1,\textit{maxPts}]\) until the total reaches \(k\), and want the probability it is still \(\le n\). \(k\) can be \(10^4\), so expanding every draw is impossible.
After the one-step difference, every state except the closed form at \(k-1\) reads a larger score first. The chain from \(0\) to \(k\) has length \(k\) and overflows the stack.
Larger scores are known if we walk downward. Let \(f[i]\) be the success probability from total \(i\), write the terminal window as \(1\), and fill from \(k-2\) down to \(0\).
Let \(f[i]\) be the probability that a current score of \(i\) ends at most \(n\). The answer is \(f[0]\).
The value of \(f[i]\) is as follows:
If \(i \ge k\), drawing stops. The value is \(1\) when \(i \le n\), and \(0\) otherwise;
Otherwise the next draw \(j\) lies in \([1,..\textit{maxPts}]\), so \(f[i] = \frac{1}{\textit{maxPts}} \sum_{j=1}^{\textit{maxPts}} f[i+j]\).
Every state depends only on a larger score, so fill from \(k - 2\) down to \(0\). When \(k = 0\) no draw has started, and the answer is \(1\).
The time complexity of the above method is \(O(k \textit{maxPts})\), which will exceed the time limit, so we need to optimize it.
We assume there are \(i\) numbers not exceeding \(n\), then \(k+i-1 \leq n\), and since \(i\leq \textit{maxPts}\), we have \(i \leq \min(n-k+1, \textit{maxPts})\), so equation \((3)\) can be written as: