1. 程式人生 > 其它 >二項式係數動態規劃 python_Python 動態規劃,反序求解

二項式係數動態規劃 python_Python 動態規劃,反序求解

技術標籤:二項式係數動態規劃 python

c56fab3ee72c92a88d4b2003d03fcda8.png

題目1:新21點

愛麗絲參與一個大致基於紙牌遊戲 “21點” 規則的遊戲,描述如下:

愛麗絲以 0 分開始,並在她的得分少於 K 分時抽取數字。 抽取時,她從 [1, W] 的範圍中隨機獲得一個整數作為分數進行累計,其中 W 是整數。 每次抽取都是獨立的,其結果具有相同的概率。

當愛麗絲獲得不少於 K 分時,她就停止抽取數字。 愛麗絲的分數不超過 N 的概率是多少?

示例 1:

輸入:N = 10, K = 1, W = 10

輸出:1.00000

說明:愛麗絲得到一張卡,然後停止。

示例 2:

輸入:N = 6, K = 1, W = 10

輸出:0.60000

說明:愛麗絲得到一張卡,然後停止。

在 W = 10 的 6 種可能下,她的得分不超過 N = 6 分。

示例 3:

輸入:N = 21, K = 17, W = 10

輸出:0.73278

提示:

0 <= K <= N <= 10000

1 <= W <= 10000

如果答案與正確答案的誤差不超過 10^-5,則該答案將被視為正確答案通過。

此問題的判斷限制時間已經減少。

Leetcode:

力扣​leetcode-cn.com

方法:動態規劃,反序求解

1.設dp[i]表示從i開始抽取數字,分數不超過N的概率

2.初始化後(K,min(N+1,K+W))個值,大於N的概率為0,小於N的概率為1

3.狀態方程:因為後面的狀態對前面產生影響,所以反向求解

dp[i] = (dp[i+1]+...+dp[i+W])/W

時間複雜度為O(min(N,K+W)),空間複雜度為O(K+W)

class Solution:
    def new21Game(self, N: int, K: int, W: int) -> float:
        dp = [0.0]*(K+W)

        for i in range(K,min(N+1,K+W)):
            dp[i] = 1.0
        
        S = min(N-K+1,W)
        for i in range(K-1,-1,-1):
            dp[i] = S/float(W)
            S += dp[i]-dp[i+W]
        return dp[0]

題目2:

在一個火車旅行很受歡迎的國度,你提前一年計劃了一些火車旅行。在接下來的一年裡,你要旅行的日子將以一個名為 days 的陣列給出。每一項是一個從 1 到 365 的整數。

火車票有三種不同的銷售方式:

一張為期一天的通行證售價為 costs[0] 美元;

一張為期七天的通行證售價為 costs[1] 美元;

一張為期三十天的通行證售價為 costs[2] 美元。

通行證允許數天無限制的旅行。 例如,如果我們在第 2 天獲得一張為期 7 天的通行證,那麼我們可以連著旅行 7 天:第 2 天、第 3 天、第 4 天、第 5 天、第 6 天、第 7 天和第 8 天。

返回你想要完成在給定的列表 days 中列出的每一天的旅行所需要的最低消費。

leetcode:

力扣​leetcode-cn.com

方法1:動態規劃,正向求解

設dp[i]表示第i天的最低消費

初始化dp[i]全為0

關係式:

if i == days[i]:

dp[i] = min(dp[max(0,i-1)]+costs[0],dp[max(0,i-7)]+costs[1],dp[max(0,i-30)]+costs[2])

else:

dp[i] = dp[i-1]

class Solution:
    def mincostTickets(self, days: List[int], costs: List[int]) -> int:
        dp = [0]*(days[-1]+1)
        days_index = 0

        for i in range(1, len(dp)):
            if days[days_index]==i:
                dp[i] = min(dp[max(0,i-1)]+costs[0],
                            dp[max(0,i-7)]+costs[1],
                            dp[max(0,i-30)]+costs[2])
                days_index +=1
            else:
                dp[i] = dp[i-1]
        return dp[-1]

方法2:動態規劃,反向求解

設dp[i]表示從第i天到最後一天的最低消費

關係式:

如果i in days:

dp[i] = min(dp[i+1]+costs[0], dp[i+7]+costs[1], dp[i+30]+costs[2])

否則:

dp[i] = dp[i+1]

class Solution:
    def mincostTickets(self, days: List[int], costs: List[int]) -> int:
        dp = [0]*(days[-1]+31)
        
        for i in range(days[-1],-1,-1):
            if i in days:
                dp[i] = min(dp[i+1]+costs[0], dp[i+7]+costs[1], dp[i+30]+costs[2])
            else:
                dp[i] = dp[i+1]

        return dp[0]

ps:共同進步,歡迎大家批評指正!