[LeetCode] 416. Partition Equal Subset Sum

来源:互联网 发布:中国网络电视在线直播 编辑:程序博客网 时间:2024/06/05 16:55

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

 

问题描述:

给定一非空数组,数组元素均为正整数,试问是否可以将数组划分成两个互补的子集,两子集的元素之和相等。

 

让我们尝试用0-1背包问题的思路,对该问题进行求解。

 

1.    0-1背包问题

 

已知我们的背包的容积为C。

假定有一系列物件,每个物件i的价值为v[i],所占的体积为c[i]。

试问在不超过背包所能容纳能力的情况下,背包中的所有的物件的最大总价值为多少。

 

对此,我们所建立的状态转移方程为:

dp[i][j] = max(dp[i – 1][j], dp[i – 1][j –c[i]] + v[i]);

 

dp[i][j]代表在仅使用前i个物件,上限容积为j的情况下,所能达到的最大总价值

 

状态转移方程中关键点就是,是否将第i个物件放入背包中。

Case 1: 第i个物件不放入背包中,为此可用上限容积不变。

Case 2:第i个物件放入背包中,可用上限容积相应减少,相应的带来了v[i]的价值。

 

 

 

2.    0-1背包问题过渡

 

如果试着把上述问题稍加变化,变成我们希望尽可能的塞满整个书包呢?

我们只需要把v[i]替换成c[i].

 

原问题中,是在给定书包容积的情况下,尽可能地获取最大的总价值。

 

那么,经过我们这一替换,问题就变成了,是在给定书包容积的情况下,尽可能地获取最大的总体积。

 

但是,总体积总是受限于书包容积,故也就是,在给定书包容积的情况下,尽可能地逼近书包容积。

 

形式化的描述就是:

 

背包的上限容积为C.

每个物件i,价值v[i],体积为c[i].

在不超过上限容积的情况下,使得背包中的物件的总体积最接近背包实际上限容积。

 

dp[i][j]:

在仅使用前i个物件,容积上限为j的情况下,背包中的物件的最大总体积

 

dp[n][C]就是我们最终所要求解的。

 

状态转移方程:

dp[i][j] = max(dp[i - 1][j], dp[i - 1][j -c[i]] + c[i]);

 

 

3.    Partition Equal Subset Sum

 

再回过头来看我们的问题,

我们是不是可以理解成,

如何从一堆体积已知的物件当中,挑出那么几个,来正好塞满其中一个背包,然后剩下的物件又正好塞满另一个同等体积的背包呢?

 

所有物件的体积都已知,故我们可以求出上述背包的体积C = sum / 2;

 

故问题就等价于dp[n][C] == C

 

状态转移方程就是:

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

 

 

 

 

 

原创粉丝点击