[Leetcode - Dynamic Programming] Partition Equal Subset Sum

Partition Equal Subset Sum 數組

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.code

Note:
Each of the array element will not exceed 100.
The array size will not exceed 200.
Example 1:element

Input: [1, 5, 11, 5]it

Output: trueio

Explanation: The array can be partitioned as [1, 5, 5] and [11].
Example 2:class

Input: [1, 2, 3, 5]動態規劃

Output: falseco

Explanation: The array cannot be partitioned into equal sum subsets.new

1.解題思路
此問題屬於動態規劃中的揹包問題。
揹包問題:假設有n個寶石,只有一個容量爲C的揹包,且第i個寶石所對應的重量和價值爲w[i]和v[i],求裝哪些寶石能夠得到最大的價值收益?
思路:咱們將n個寶石進行編號,0,1,2...n-1,尋找DP的狀態和狀態轉移方程。咱們用dpij表示將前i個寶石裝到剩餘容量爲j的揹包中,那麼久很容易獲得狀態轉移方程了。(寶石從0開始編號,因此dpij是在考慮第i-1個寶石裝包的狀況,固然咱們要先初始化前0個寶石裝包的狀況,即dp0=0,由於不裝任何寶石,因此不管如何價值都爲0.)return

dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-w[i-1]]+v[i-1])
揹包沒法再裝下第i-1個寶石-> dp[i-1][j];
繼續將第i-1個寶石裝包->  dp[i-1][j-w[i-1]]+v[i-1]。

搞清楚了揹包問題,這個Partition Equal Subset Sum的題目就迎刃而解了。
1). 判斷數組中全部數的和是否爲偶數,由於奇數是不可能有解的;
2). 根據揹包問題,取前i個數,體積爲j的狀況下,

dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-nums[i-1]]+nums[i-1])

3).若是最後dpnums.length=sum/2,則返回true.

2.代碼

public class Solution {
    public boolean canPartition(int[] nums) {
        if(nums.length==0) return false;
        int sum=0;
        for(int n:nums){
            sum+=n;
        }
        if(sum%2==1) return false;
        sum=sum/2;
        int[][] dp=new int[nums.length+1][sum+1];
        for(int i=0;i<=nums.length;i++){
            for(int j=0;j<=sum;j++){
                if(i==0) //表示前0個數,因此價值均爲0;
                    dp[i][j]=0;
                //在裝第i-1個數時,先判斷剩餘容量j是否大於nums[i-1]
                else if(j<nums[i-1]) dp[i][j]=dp[i-1][j]; //小於表示空間不夠,因此維持不變
                else{
                //空間夠,就經過比較大小來判斷是否該放入第i-1個數
                    dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-nums[i-1]]+nums[i-1]);
                }
            }
        }
        return dp[nums.length][sum]==sum;
    }
}
相關文章
相關標籤/搜索