[leetCode]837.新21点
这道题目需要用到动态规化,爱丽丝获胜的条件是得分x小于等于N。根据示例3,假设当前得分x为16,那么再抽一牌可能为[1-10]中的一张,其中抽到[1,5]时得分x<N,抽到[6,10]时得分大于N,因此
f
(
16
)
=
1
10
∗
(
1
+
1
+
1
+
1
+
1
+
0
+
0
+
0
+
0
+
0
)
=
0.5
f(16)=\frac {1}{10}*(1+1+1+1+1+0+0+0+0+0)=0.5
f(16)=101∗(1+1+1+1+1+0+0+0+0+0)=0.5
f
(
x
)
=
1
W
∗
(
f
(
x
+
1
)
+
f
(
x
+
2
)
+
f
(
x
+
3
)
+
.
.
.
+
f
(
x
+
W
)
)
f(x)=\frac {1}{W}*(f(x+1)+f(x+2)+f(x+3)+...+f(x+W))
f(x)=W1∗(f(x+1)+f(x+2)+f(x+3)+...+f(x+W))
当x=15 时
f
(
15
)
=
1
10
∗
0.5
+
1
10
∗
(
1
+
1
+
1
+
1
+
1
+
0
+
0
+
0
+
0
)
=
0.5
f(15)=\frac {1}{10}*0.5+\frac {1}{10}*(1+1+1+1+1+0+0+0+0)=0.5
f(15)=101∗0.5+101∗(1+1+1+1+1+0+0+0+0)=0.5
f
(
x
−
1
)
=
1
W
∗
(
f
(
x
)
+
f
(
x
+
1
)
+
f
(
x
+
2
+
f
(
x
+
3
)
+
.
.
.
+
f
(
x
+
W
−
1
)
)
f(x-1)=\frac {1}{W}*(f(x)+f(x+1)+f(x+2+f(x+3)+...+f(x+W-1))
f(x−1)=W1∗(f(x)+f(x+1)+f(x+2+f(x+3)+...+f(x+W−1))
所以就得到了转移方程f(x);
C++
class Solution {
public:
double new21Game(int N, int K, int W) {
if(K==0)return 1.0;
vector<double> dp(N+W);//声明一个数组,用于保存得分为K情况下开始游戏,爱丽丝获胜的概率(分数不超过N)
//先初始化dp;当K = 16 时,再抽一张牌能获得的最大分数为26最小分数为1,如果抽的为[1,5]爱丽丝获胜,抽的为[6,10]则失败
//dp[17,26]为[1,1,1,1,1,0,0,0,0,0]
for(int i = K; i < N+1; i++)//当N大于K+W时会出现out of range
dp[i]=1.0;
//从后往前计算dp[16]、dp[15]
double tem = min(N-K+1,W);//tem表示后面10个概率相加最多只能为10
for(int i = K - 1; i>=0; i--){
dp[i]=tem/W;
tem += dp[i]-dp[i+W];
}
return dp[0];
}
};