01 Backpack problem
This article is very clear, I will not repeat it here.
https://www.cnblogs.com/Christal-R/p/Dynamic_programming.html
leetcode problem 416
describe
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.
That is, it is judged whether the given array can be divided into two parts so that their sums are equal.
analyze
The problem is to find a sequence from an array so that their sum is sum/2. If the solution is brute force, the number of selected array subsequences is not fixed, and the complexity is too high, which is definitely not desirable. In fact this is a 01 knapsack problem, for each number it is either checked or unchecked.
Specifically, a two-dimensional array d[i][j] is used to represent whether the sum j can be calculated by selecting a subsequence from the first i elements. Then we only need to know whether d[i][j] is true when j=sum/2.
There are two cases for the result of d[i][j]
- d[i-1][j] is already true, that is to say, the sum j can be calculated by selecting the subsequence from the first i-1 elements, then d[i][j] is naturally true.
- d[i-1][j-nums[i]] is true, that is to say, select the subsequence in the first i-1 elements to calculate the sum of j-nums[i], then adding nums[i] is just enough Finish.
python code
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]