ARIS - 1

509 阅读2分钟

A


837 .新21点

描述

爱丽丝参与一个大致基于纸牌游戏 “21点” 规则的游戏,描述如下:

爱丽丝以 0 分开始,并在她的得分少于 K 分时抽取数字。 抽取时,她从 [1, W] 的范围中随机获得一个整数作为分数进行累计,其中 W 是整数。 每次抽取都是独立的,其结果具有相同的概率。

当爱丽丝获得不少于 K 分时,她就停止抽取数字。 爱丽丝的分数不超过 N 的概率是多少?

思路

核心是以分数 K 为分界点,分为 K 之前和 K 之后的两部分,然后根据相邻分数之间的关系进行逐级推导。在此基础上有从前推导和从后推导两种。

从前推导

建立dp[N+1]数组,其中dp[i]是累计分数为i时的概率。则获胜概率即为分数不超过N的概率,为从dp[K]dp[N]的和的累加。

其中dp[0]=1, dp[1]=\frac{1}{W}

i \in [2, K] ,可以得到

dp[i]=\frac{dp[i-1]+dp[i-2]+...+dp[i-W]}{W}

结合dp[i-1] 的值,可以简化为

dp[i]={\frac{W+1}{W}}\times{dp[i-1]}-{\frac{1}{W}}\times{dp[i-1-W]}

i\in(K,N],可以得到

dp[i]=\frac{dp[K-1]+dp[K-2]+...+dp[i-W]}{W}

结合dp[i-1]的值,可以简化为

dp[i]=dp[i-1]-{\frac{1}{W}}\times{dp[i-1-W]}

从后推导

建立dp[K+W]数组,其中dp[i]是从分数为i时开始抽取的获胜概率。dp[0]即为最终要获取的求胜概率。

i \in [K, K+W) 中,可以得到

dp[i] = i <= N ? 1 : 0

i \in [0, K) 中,可以得到

dp[i]=\frac{dp[i+1]+dp[i+2]+...+dp[i+W]}{W}

结合dp[i+1]的值,可以简化为

dp[i]={\frac{W+1}{W}}\times{dp[i+1]}-{\frac{1}{W}}\times{dp[i+1+W]}

其中dp[K-1]比较特殊,因为K+W超限了,不能使用上面的简化公式,需要单独计算,但因为[K, K+W)区间内的值只有在小于N时才为1,故可以简化为:

dp[K-1]=\frac{min(N, K+W-1)-(K-1)}{W}=\frac{min(N-(K-1), W)}{W}

R


You don’t (always) need [weak self]

文章介绍了应该在什么时候使用 weak self 和闭包中使用时的一些注意事项。

  • unowned self能不用就不用。
  • 非逃逸闭包如果不会在dealloc之后执行,不需要使用weak self
  • 逃逸闭包在闭包被self持有或其被传递进的另一个闭包被self持有时,需要使用weak self
  • guard let sself = self这种方式在使用后在闭包结束前会强持有self,如果在闭包里有耗时很长的操作,要考虑它对selfdealloc的影响。
  • GCD 和动画调用时,如果没有把它们作为属性保存,不需要使用weak self
  • 在使用定时或延时任务时要考虑它对selfdealloc的影响。

T


  1. 在通过 SnapKit 或 Masonry 来约束 UIScrollView 时,不需要为 UIScrollview 设置 contentSize ,但是需要设置上下或左右约束,设置了约束之后,在 UIScrollview 内部的 view 的大小超出 UIScrollView 的可见范围时,才能滚动。
  2. 如果想实现 UIScrollview 内部左右贴边展示的效果,在为内部 view 设约束时,其 leading 和 trailing 不能指向 UIScrollView ,而是需要指向 UIScrollView 的 superview 或同级 view ,否则展示时不会压缩或截断,而是变成左右滚动的样式。

R


PyQt5 的安装与使用