动态规划之01背包问题及leetcode实例

01背包问题

这篇文章讲的很清楚,我这里就不赘述了。

https://www.cnblogs.com/Christal-R/p/Dynamic_programming.html

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]
    原文作者:动态规划
    原文地址: https://blog.csdn.net/c_j33/article/details/79151061
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞