1. 程式人生 > >再學動態規劃之 01揹包

再學動態規劃之 01揹包

寫了之後,發現這題跟01揹包還有點區別。但是寫看這個吧。
暴力搜尋的方法。就是每個取或者不去。

class Solution(object):
    def getS(self, arr, index, target):
    	if target == 0:
    		return True
    	elif target < 0:
    		return False
    	else:
	        if index == len(arr)-1:
	            if arr[index] == target:
	                return True
else: return False else: return self.getS(arr, index+1, target) or self.getS(arr, index+1, target-arr[index]) def canPartition(self, nums): """ :type nums: List[int] :rtype: bool """ total = sum(nums) if
total%2 == 1: return False target = total/2 return self.getS(nums, 0, target)

超時是必然的。接下來,我們把目前 考慮index和目標target記錄下來:

rec_dict = dict()
class Solution(object):
    def getS(self, arr, index, target):
    	if target == 0:
    		return True
    	elif target < 0:
    		return
False else: if index == len(arr)-1: if arr[index] == target: return True else: return False else: temp = str(index)+'_'+str(target) if temp in rec_dict: return rec_dict[str(index)+'_'+str(target)] else: rec_dict[str(index)+'_'+str(target)] = self.getS(arr, index+1, target) or self.getS(arr, index+1, target-arr[index]) return rec_dict[str(index)+'_'+str(target)] def canPartition(self, nums): """ :type nums: List[int] :rtype: bool """ rec_dict.clear() total = sum(nums) if total%2 == 1: return False target = total/2 return self.getS(nums, 0, target)

這下通過了。但是我們發現這裡 存在眾多的遞迴呼叫。這就是因為沒有按順序計算的結果。這也引入了動態規劃:

class Solution(object):
    def canPartition(self,nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        total = sum(nums)
        if total % 2 == 1:
            return False
        target = total / 2
        arr = [[False for _ in range(target+1)] for _ in range(len(nums)+1)]
        for ix in range(len(arr)):
            arr[ix][0] = True
        for i in range(1, len(nums) + 1):
            for j in range(1, target + 1):
                if j - nums[i - 1] >= 0:
                    arr[i][j] = (arr[i - 1][j - nums[i - 1]] or arr[i - 1][j])
                else:
                    arr[i][j] = arr[i - 1][j]
            if arr[i][target] == True:
                return True
        return False

之前用

arr = [[False]*x]*y

接下來是有趣的解法

class Solution(object):
    def canPartition(self,nums):
        """
        :type nums: List[int]
        :rtype: bool
        """
        possible_sum = {0}
        for num in nums:
            possible_sum.update({v+num for v in possible_sum})
        return sum(nums)/2. in possible_sum

意思就是 直接把可能的和加出來。。。。