LeetCode.837 New 21 Game

题目描述和分析

LeetCode.837的原题叙述比较繁琐,有需求的同学可以自行链接,这里给出一个简化版本。初始点数为0,每次从 [ 1 , W ] [1,W] [1,W]中独立同分布地随机选取一个整数,并累积起来,直到累积和大于等于 K K K为止。请问累积点数小于等于 N N N的概率?( W W W K K K N N N都为正整数且 K &lt; = N K&lt;=N K<=N)假设事件采取数字的累积和为 X X X,所以根据题意所需求的概率为,

p ( K ≤ X ≤ N ) p(K\le X \le N) p(KXN)

举一个简单的例子,

I n p u t : N = 6 , K = 1 , W = 10 → p = 0.6 Input: N=6,K=1,W=10 \to p = 0.6 Input:N=6,K=1,W=10p=0.6

这个例子求解非常简单,因为只需采样一次便可以满足大于等于 K K K这一条件,故事件的概率为 p ( X &ThickSpace; w h i c h &ThickSpace; 1 ≤ X ≤ 6 ) = 0.1 p(X \; which \; 1\le X \le6) =0.1 p(Xwhich1X6)=0.1,接下来累积便可。这个例子很难说明问题的本质,编写的程序需要解决的是一个普遍问题,而不是特例。我们取个稍微大一点的 K ( = 3 ) K(=3) K(=3),并且从 X = 1 X=1 X=1开始计算概率,

X = 1 : p ( a 1 = 1 ) = 0.1 X=1: p(a_1=1) = 0.1 X=1:p(a1=1)=0.1

X = 2 : p ( a 1 = 2 ) + p ( a 1 = 1 , a 2 = 1 ) = 0.1 + 0.01 X=2: p(a_1=2) + p(a_1=1,a_2=1) = 0.1 + 0.01 X=2:p(a1=2)+p(a1=1,a2=1)=0.1+0.01

X = 3 : p ( a 1 = 3 ) + p ( a 1 = 1 , a 2 = 2 ) + p ( a 1 = 2 , a 1 = 2 ) + p ( a 1 = 0.1 , a 2 = 0.1 , a 3 = 0.1 ) = 0.1 + 0.01 + 0.01 + 0.001 X=3: p(a_1=3) + p(a_1=1,a_2=2) + p(a_1=2,a_1=2) \\ + p(a_1=0.1,a_2=0.1,a_3=0.1) = 0.1 + 0.01 + 0.01 + 0.001 X=3:p(a1=3)+p(a1=1,a2=2)+p(a1=2,a1=2)+p(a1=0.1,a2=0.1,a3=0.1)=0.1+0.01+0.01+0.001

对数列稍作转换,

p ( X = 0 ) = 1 p(X=0) = 1 p(X=0)=1

p ( X = 1 ) = 0.1 × 1 p(X=1) = 0.1 \times 1 p(X=1)=0.1×1

p ( X = 2 ) = 0.1 × ( 1 + 0.1 ) p(X=2) = 0.1 \times (1 + 0.1) p(X=2)=0.1×(1+0.1)

p ( X = 3 ) = 0.1 × ( 1 + 0.1 + 0.1 × ( 1 + 0.1 ) ) p(X=3) = 0.1 \times (1 + 0.1 + 0.1\times(1+0.1)) p(X=3)=0.1×(1+0.1+0.1×(1+0.1))

便可以找到一个递推式 p ( X = i ) = 1 W ∑ k i − 1 p ( X = k ) p(X=i) = \frac{1}{W}\sum_{k}^{i-1}p(X=k) p(X=i)=W1ki1p(X=k),当然,这个公式仅在 X ≤ 3 X\le3 X3时是符合的,

X = 4 : p ( a 1 = 4 ) + p ( a 1 = 1 , a 2 = 3 ) + p ( a 1 = 2 , a 2 = 2 ) + p ( a 1 = 1 , a 2 = 1 , a 3 = 2 ) = 0.121 X=4: p(a_1=4)+p(a_1=1,a_2=3)+p(a_1=2,a_2=2) \\ + p(a_1=1,a_2=1,a_3=2)=0.121 X=4:p(a1=4)+p(a1=1,a2=3)+p(a1=2,a2=2)+p(a1=1,a2=1,a3=2)=0.121

X = 5 : p ( a 1 = 5 ) + p ( a 1 = 1 , a 2 = 4 ) + p ( a 1 = 4 , a 2 = 1 ) + p ( a 1 = 1 , a 2 = 1 , a 3 = 4 ) = 0.121 X=5: p(a_1=5)+p(a_1=1,a_2=4)+p(a_1=4,a_2=1) \\ + p(a_1=1,a_2=1,a_3=4)=0.121 X=5:p(a1=5)+p(a1=1,a2=4)+p(a1=4,a2=1)+p(a1=1,a2=1,a3=4)=0.121

可以看到概率值和 p ( X = 3 ) p(X=3) p(X=3)都是一样,诸如 X = 5 X=5 X=5往后不需要添加 X = 4 X=4 X=4的情况。

还有一个点很容易被忽略,在翻看了论坛才发现(建议同学们可以上英文版LeetCode,上面的论坛比较活跃)。当在累积概率的过程中, X &gt; W X&gt;W X>W不能简单地从头累积,而是设定一个窗口 ∑ i = X − W X − 1 \sum_{i=X-W}^{X-1} i=XWX1。具体的代码如下,

代码

double new21Game(int N, int K, int W) {
    if (K == 0 || N >= K + W) 
        return 1.0;
    
    vector<double> dp(N + 1);
    dp[0] = 1.0;
    double Wsum = 1.0, res = 0.0;
    
    for (int i = 1; i <= N; ++i) {
        dp[i] = Wsum / W;
        if (i < K) Wsum += dp[i]; else res += dp[i];
        if (i - W >= 0) Wsum -= dp[i - W];
    }
    
    return res;
}

一次遍历,效率达到top级。(代码和解法是出题者在论坛中给出的,这道题非常值得琢磨)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值