1. 程式人生 > >動態規劃之01揹包問題及leetcode例項

動態規劃之01揹包問題及leetcode例項

01揹包問題

這篇文章講的很清楚,我這裡就不贅述了。

leetcode problem 416

描述

Given a non-empty array containing only positive integers,
find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.

即判斷能不能將給定陣列分成兩份,使他們的和相等。

分析

題目就是要從陣列中找一個序列,使他們的和為sum/2。如果暴力硬解,挑選的陣列子序列個數不定,複雜度太高,肯定不可取。事實上這是一個01揹包問題,對於每個數字,要麼選中要麼不選中。

具體的,用一個二維陣列d[i][j]表示,從前i個元素中挑選子序列是否可以計算出和j。那麼我們只要知道當j=sum/2的時候,d[i][j]是否為true。

d[i][j]結果的得出,可以有兩種情況

  • d[i-1][j]已經為true,也就是說,已經可以由前i-1個元素中挑選子序列計算出和j,那麼d[i][j]自然為true。
  • d[i-1][j-nums[i]]為true,也就是說,前i-1個元素中挑選子序列計算出和j-nums[i],那麼加上nums[i]剛好可以完成。

python程式碼

def canPartition(nums):
    """
    :type nums: List[int]
    :rtype: bool
    """
half_sum = sum(nums) if half_sum % 2 == 1: return False half_sum = half_sum / 2 d = [[False for x in xrange(half_sum + 1)] for y in xrange(len(nums) + 1)] for k in xrange(len(nums) + 1): d[k][0] = True for i in xrange(1, len(nums) + 1): for j in xrange(0
, half_sum + 1): d[i][j] = d[i - 1][j] if j >= nums[i - 1]: d[i][j] = d[i][j] | d[i - 1][j - nums[i - 1]] return d[len(nums)][half_sum]