LeetCode之動態規劃揹包問題實操

2021-09-29 08:37:38 字數 3172 閱讀 4589

if sum_total % 2: # 若總為奇數, 則不能被分割成兩個子集

return false

pack_capcity = sum_total // 2 # 揹包大小

dp = [float('-inf')] * (pack_capcity + 1)

dp[0] = 0

for i in range(len(nums)):

for j in range(pack_capcity, nums[i]-1, -1):

dp[j] = max(dp[j], dp[j-nums[i]] + nums[i])

if dp[-1] > 0: # 剪枝操作,當dp[-1]>0時可以確定存在可行劃分... 不剪枝會超時

return true

return false

這道題目也可以用逐個過濾元素的方法來做,先大到小排序以減少過濾次數。

# 56ms

class solution:

def canpartition(self, nums: list[int]) -> bool:

if len(nums) == 0:

return true

if sum(nums)%2 == 1:

return false

half = sum(nums)//2

nums.sort(reverse=true)

def search(target, numlist):

if len(numlist)==0:

return false

if target in numlist:

return true

if target將問題轉化成01揹包問題

這種想法比較巧妙,一開始我也想到用01揹包求解,但是不知道怎麼處理負數的問題以及如何奇數的問題。我們來看如下例子:

nums = , target=3, 一種可行的方案是+1-2+3-4+5 =3

該方案中陣列元素可以分為兩組,一組是數字符號為正(p=),另一組數字符號為負(n=)

因此: sum(1,3,5) - sum(2,4) = target

sum(1,3,5) - sum(2,4) + sum(1,3,5) + sum(2,4) = target + sum(1,3,5) + sum(2,4)

2sum(1,3,5) = target + sum(1,3,5) + sum(2,4)

2sum(p) = target + sum(nums)

sum(p) = (target + sum(nums)) / 2

由於target和sum(nums)是固定值,因此原始問題轉化為求解nums中子集的和等於sum(p)的方案個數問題

class solution:

def findtargetsumways(self, nums, s):

if sum(nums) < s or (sum(nums) + s) % 2 == 1: return 0

p = (sum(nums) + s) // 2

dp = [1] + [0 for _ in range(p)]

for num in nums:

for j in range(p, num - 1, -1):

# dp[i] 的解法數為自身加上dp[i-num]的解法數

# 這裡為什麼會如此,可以參考斐波那契數列

# 這裡我可以不放 num 進揹包,解法數為 dp[i]

# 將 num 放進揹包,解法數為 dp[i-num]

# 所以此時的總解法數為 二者和

說明:這個是需要正好裝滿整個揹包,取個數的最小數。狀態轉移時可以用min來取較小者。

# dp = [[0]*(n+1) for _ in range(m+1)] #準備很多個揹包

for one in strs:

item_count0 = one.count('0')

item_count1 = one.count('1')

for i in range(m, item_count0-1, -1):

for j in range(n, item_count1-1, -1):

dp[i][j] = max(dp[i][j], dp[i-item_count0][j-item_count1]+1)

return dp[m][n]

動態規劃之01揹包

動態規劃的基本思想 將乙個問題分解為子問題遞迴求解,且將中間結果儲存以避免重複計算。通常用來求最優解,且最優解的區域性也是最優的。求解過程產生多個決策序列,下一步總是依賴上一步的結果,自底向上的求解。動態規劃演算法可分解成從先到後的4個步驟 1.描述乙個最優解的結構,尋找子問題,對問題進行劃分。2....

動態規劃之01揹包

01揹包問題,是用來介紹動態規劃演算法最經典的例子,網上關於01揹包問題的講解也很多,我寫這篇文章力爭做到用最簡單的方式,最少的公式把01揹包問題講解透徹。f i,j 表示在前i件物品中選擇若干件放在承重為 j 的揹包中,可以取得的最大價值。pi表示第i件物品的價值。決策 為了揹包中物品總價值最大化...

動態規劃之揹包問題

最近刷題遇到好幾道揹包問題,揹包問題是動態規則中的一類體型,在考察演算法的筆試中經常遇到。關於揹包問題,文章 揹包問題九講 中已經做了很多分析,這裡就不再細述,建議好好看看這篇文章。然而文章給了許多案例分析,卻沒有很好的練習。說明 1 本文目的不在於講解揹包問題的分析與講解,而是收集了一些揹包問題。...