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.
Input: n =6, k =1, maxPts =10Output: 0.60000Explanation: Alice gets a single card, then stops.In 6out of 10 possibilities, she is at or below 6 points.
We use DP where dp[x] is the probability of getting exactly x points. For each state, the probability is the average of the previous maxPts states. To optimize, we use a sliding window sum.
classSolution {
public:double new21Game(int n, int k, int maxPts) {
if (k ==0|| n >= k + maxPts -1) return1.0;
vector<double> dp(n+1);
dp[0] =1.0;
double window =1.0, ans =0.0;
for (int i =1; i <= n; ++i) {
dp[i] = window / maxPts;
if (i < k) window += dp[i];
else ans += dp[i];
if (i - maxPts >=0) window -= dp[i - maxPts];
}
return ans;
}
};
classSolution {
publicdoublenew21Game(int n, int k, int maxPts) {
if (k == 0 || n >= k + maxPts - 1) return 1.0;
double[] dp =newdouble[n+1];
dp[0]= 1.0;
double window = 1.0, ans = 0.0;
for (int i = 1; i <= n; ++i) {
dp[i]= window / maxPts;
if (i < k) window += dp[i];
else ans += dp[i];
if (i - maxPts >= 0) window -= dp[i - maxPts];
}
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution {
funnew21Game(n: Int, k: Int, maxPts: Int): Double {
if (k ==0|| n >= k + maxPts - 1) return1.0val dp = DoubleArray(n+1)
dp[0] = 1.0var window = 1.0var ans = 0.0for (i in1..n) {
dp[i] = window / maxPts
if (i < k) window += dp[i]
else ans += dp[i]
if (i - maxPts >=0) window -= dp[i - maxPts]
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution:
defnew21Game(self, n: int, k: int, maxPts: int) -> float:
if k ==0or n >= k + maxPts -1:
return1.0 dp = [0.0] * (n+1)
dp[0] =1.0 window =1.0 ans =0.0for i in range(1, n+1):
dp[i] = window / maxPts
if i < k:
window += dp[i]
else:
ans += dp[i]
if i - maxPts >=0:
window -= dp[i - maxPts]
return ans
impl Solution {
pubfnnew21_game(n: i32, k: i32, max_pts: i32) -> f64 {
if k ==0|| n >= k + max_pts -1 {
return1.0;
}
let n = n asusize;
let k = k asusize;
let max_pts = max_pts asusize;
letmut dp =vec![0.0; n+1];
dp[0] =1.0;
letmut window =1.0;
letmut ans =0.0;
for i in1..=n {
dp[i] = window / max_pts asf64;
if i < k {
window += dp[i];
} else {
ans += dp[i];
}
if i >= max_pts {
window -= dp[i - max_pts];
}
}
ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
classSolution {
new21Game(n: number, k: number, maxPts: number):number {
if (k===0||n>=k+maxPts-1) return1.0;
constdp= Array(n+1).fill(0);
dp[0] =1.0;
let window =1.0, ans=0.0;
for (leti=1; i<=n; ++i) {
dp[i] = window /maxPts;
if (i<k) window +=dp[i];
elseans+=dp[i];
if (i-maxPts>=0) window -=dp[i-maxPts];
}
returnans;
}
}