K点游戏

概率问题

题目链接:牛客网题目

题目描述
小招喵某日闲来无事,想验一下自己的人品,于是给自己定了一个游戏规则:
这个游戏有三个因素: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 K1+W 的值大于 N N N,那么当初始点数是 K − 1 K-1 K1 时,就有可能超出上限,这种情况我们要考虑进去,为了使索引和位置能对应,动态规划的范围就是 [ 0 , K − 1 + W ] [0,K-1+W] [0,K1+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,K1+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 W2 个交叉项的,比如:
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[i1]=W1(dp[i],.......dp[i+W1])
观察上面两个式子我们知道,想要计算 d p [ i − 1 ] dp[i-1] dp[i1],只需要在 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))
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值