【leetcode】837. New 21 Game


題目如下:

解題思路:這個題目有點像爬樓梯問題,只不過樓梯問題要求的計算多少種爬的方式,但是本題是計算概率。因為點數超過或者等於K后就不允許再增加新的點數了,因此我們可以確定最終Alice擁有的點數的區間是[K,K-1+W],下限等於K很好理解,Alice最后一次抽取點數前可能擁有的點數最大值是K-1,最后一次抽取的點數最大值是W,因此上限就是K-1+W。和爬樓梯類似,恰好獲得點數n的概率dp[n] = sum(dp[n-w]/w + dp[n-w+1]/w + .... dp[n-1]/w)。因為獲取任意一個點數的概率都是1/W,所以上面的公式中每個dp都要除以W。但是題目約定了一個K值,在n > k + 1的情況下,dp[n]是無法通過dp[n-1]得到,需要修正公式: dp[n] = sum(dp[n-w]/w + dp[n-w+1]/w + .... dp[K-1]/w)。最后,點數小於或者等於N的概率就是 sum(dp[K:N + 1])。

代碼如下:

class Solution(object):
    def new21Game(self, N, K, W):
        """
        :type N: int
        :type K: int
        :type W: int
        :rtype: float
        """
        low = K
        high = K - 1 + W
        if N < low or K == 0 or N > high:
            return 1.0
        dp = [0 for x in xrange(high + 1)]
        dp[0] = 0.0
        for i in xrange(1, min(high, W) + 1):
            dp[i] = float(1) / float(W)
        # print dp
        pro = 0.0
        for i in xrange(2, W + 1):
            if i > K:
                maxv = K - 1
                minv = max(i - W, 1)
            else:
                maxv = i - 1
                minv = max(i - W, 1)
            if pro == 0.0:
                for j in xrange(minv, maxv + 1):
                    pro += dp[j]/W
            else:
                if i > K:
                    pro -= dp[minv-1]/W
                else:
                    pro += dp[maxv]/W
                    pro -= dp[minv-1]/W
            dp[i] += pro
        lastWCount = sum(dp[:min(K, W + 1)])
        #print lastWCount
        for i in xrange(W + 1, len(dp)):
            dp[i] = lastWCount / W
            if i < K:
                lastWCount += dp[i]
            lastWCount -= dp[i - W]
            #print '1:',i,dp[i]
        #print 'total:',sum(dp[low:])
        #print '1',dp[K-5:K+5]
        #print dp
        return sum(dp[low:N + 1])/sum(dp[low:])

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM