概率问题
题目链接:牛客网题目
题目描述
小招喵某日闲来无事,想验一下自己的人品,于是给自己定了一个游戏规则:
这个游戏有三个因素:N,K,W
游戏开始的时候小招喵有0点,之后如果发现自己手上的点不足K点,就随机从1到W的整数中抽取一个(包含1和W),抽到哪个数字的概率都是相同的。
重复上述过程,直到小招喵获得了K或者大于K点,就停止获取新的点,这时候小招喵手上的点小于等于N的概率是多少?
输入:N = 5, K = 1, W = 5
输出:1.00000
说明:开始有0点,不足1点,从[1,5]中随机取一个整数(一共5个数字,所以每个数字取到的概率都是1/5),获得后得分无论如何都大于了1点,停止,概率为1
输入:N = 6, K = 1, W = 10
输出:0.60000
说明:开始有0点,不足1点,从[1,10]中随机取一个整数(一共10个数字,所以每个数字取到的概率都是1/10),获得后有6/10的概率小于6点,且满足大于1点的条件,概率为0.6
输入描述:
输入为3个整数,分别对应N,K,W,中间用空格隔开
其中0 <= K <= N <= 10000,1 <= W <= 10000
输出描述:
输出为概率值,保留5位小数
思路:
动态规划:设
d
p
[
i
]
dp[i]
dp[i] 是初始点为
i
i
i 时的符合题目要求的概率。
那么由题目要求知道,N是点数的上限,K是点数的下限,W是随机取点数的上限。因此当初始点 i i i 位于 [ K , N ] [K,N] [K,N] 时,此时的 d p [ i ] dp[i] dp[i] 就是1。倘若 K − 1 + W K-1+W K−1+W 的值大于 N N N,那么当初始点数是 K − 1 K-1 K−1 时,就有可能超出上限,这种情况我们要考虑进去,为了使索引和位置能对应,动态规划的范围就是 [ 0 , K − 1 + W ] [0,K-1+W] [0,K−1+W]。
其中当
i
i
i 处于
[
K
,
N
]
[K,N]
[K,N] 时,
d
p
[
i
]
=
1
dp[i]=1
dp[i]=1 ;当
i
i
i 处于
d
p
[
N
+
1
,
K
−
1
+
W
]
dp[N+1,K-1+W]
dp[N+1,K−1+W] 时,
d
p
[
i
]
=
0
dp[i]=0
dp[i]=0。
而动态规划的核心公式就是
d
p
[
i
]
=
1
W
(
d
p
[
i
+
1
]
,
.
.
.
.
.
.
.
d
p
[
i
+
W
]
)
dp[i] = \frac{1}{W}(dp[i+1],.......dp[i+W])
dp[i]=W1(dp[i+1],.......dp[i+W])因此动态规划的计算公式是由后往前推,刚刚已经讲了初始化后面的
W
W
W 个
d
p
[
i
]
dp[i]
dp[i] ,因此直接循环计算即可。但是我们发现,相邻的动态数组元素的计算其实是有
W
−
2
W-2
W−2 个交叉项的,比如:
d
p
[
i
]
=
1
W
(
d
p
[
i
+
1
]
,
.
.
.
.
.
.
.
d
p
[
i
+
W
]
)
dp[i]= \frac{1}{W}(dp[i+1],.......dp[i+W])
dp[i]=W1(dp[i+1],.......dp[i+W])
d
p
[
i
−
1
]
=
1
W
(
d
p
[
i
]
,
.
.
.
.
.
.
.
d
p
[
i
+
W
−
1
]
)
dp[i-1]= \frac{1}{W}(dp[i],.......dp[i+W-1])
dp[i−1]=W1(dp[i],.......dp[i+W−1])
观察上面两个式子我们知道,想要计算
d
p
[
i
−
1
]
dp[i-1]
dp[i−1],只需要在
d
p
[
i
]
dp[i]
dp[i] 的公式基础上加一项
d
p
[
i
]
dp[i]
dp[i], 再减一项
d
p
[
i
+
W
]
dp[i+W]
dp[i+W] 即可。
因此代码很清晰,如下:
if __name__=='__main__':
n, k, w = list(map(int, input().split()))
dp = [0]*(k+w)
for i in range(k, n+1):
dp[i] = 1
s = min(w, n-k+1)
for i in range(k-1, -1, -1):
dp[i] = s / w
s += dp[i] - dp[i+w]
print(round(dp[0],5))