837. 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 <= 104

  • 1 <= maxPts <= 104

Solution

  • The final result shall be between K and K-1+W

  • if the N is greater than K-1+W, then for any cases the result satisfied the demand, so possiblily is 1

  • If the N is smaller than K, then for any cases the result *never satisfied, so it is 0

  • For other cases

    • Consider the possiblily of getting each number i

      • P(i) = P(i-1)/W + P(i-2)/W + .....P(i-W)/W = Sum(P(i-1) + .... P(i-W)) / W

        • Practically tips:

          • Shall maintain a windows to record the sum of P*

            • keep adding the new P(i)

            • get rid of the old P (i-w)

      • Search for the possiblites sum of P(i) where i <= N

  public double new21Game(int N, int K, int W) {
        if(N > K + W - 1 || K == 0) return 1;
        double[] dp = new double[N+1];
        double posSum = 1, res = 0;
        dp[0] = 1;
        for(int i = 1; i < dp.length; i++){
            dp[i] = posSum /W;
            if(i < K)
            {
                posSum += dp[i]; //adding new P(i)
            }
            else{
                res += dp[i];
            }
            
            if(i-W >= 0){
                posSum -= dp[i-W];
                //get rid of the old P(i-w), 
                //keep the posSum still provides sum of corect range 
            }
        }
        return res;
        
    }

Last updated

Was this helpful?