分割等和子集 動態規劃

2022-07-08 11:51:10 字數 3647 閱讀 5928

給定乙個只包含正整數非空陣列。是否可以將這個陣列分割成兩個子集,使得兩個子集的元素和相等。

注意:

每個陣列中的元素不會超過100

陣列的大小不會超過200

示例 1:

輸入: [1, 5, 11, 5]

輸出: true

解釋: 陣列可以分割成 [1, 5, 5] 和 [11].

示例 2:

輸入: [1, 2, 3, 5]

輸出: false

解釋: 陣列不能分割成兩個元素和相等的子集.

public boolean canpartition(int nums) 

int sum = 0, maxnum = 0;

for (int num : nums)

if (sum % 2 != 0)

int target = sum / 2;

if (maxnum > target)

boolean dp = new boolean[n][target + 1];

for (int i = 0; i < n; i++)

dp[0][nums[0]] = true;

for (int i = 1; i < n; i++) else

} }return dp[n - 1][target];

}

這裡要將陣列劃分為兩個子集,陣列至少要有兩個元素。

如果陣列中所有元素的和sum是奇數,不可能劃分出元素和相等的兩個子集;如果sum是偶數,則令target=sum/2,需要判斷是否可以從陣列中選出一些數字,使得這些數字的和等於target

如果陣列中最大的元素maxnum大於target,則除了maxnum以外的所有元素之和一定小於target,因此也不可能劃分出元素和相等的兩個子集。

建立二維陣列dp,包含ntarget+1列,其中dp[i][j]表示從陣列的[0,i]下標範圍內選取若干個正整數(可以是0個),是否存在一種選取方案使得被選取的正整數的和等於j

i = 0時,選取nums[0]使得j等於1

i = 1時,有三種情況:

選取nums[0]使得j等於1

選取nums[1]使得j等於5

同時選取nums[0]nums[1]使得j等於6

注意到當i = 1時,要使得j等於1,由於nums[1]大於1,所以不選取nums[1]

因此,dp[1][1] = dp[0][1],即不選取nums[1]的情況下,是否存在使得j等於1的選取方案。

i = 1時,要使得j等於5,由於nums[1]小於等於5。因此,dp[1][5] = dp[0][5] | dp[0][0],這裡的dp[0][5]表示不選取nums[1],是否存在使得j等於5的選取方案,dp[0][0]表示選取nums[1],是否存在一種選取方案使得被選取的正整數的和等於0

i = 1時,要使得j等於6,由於nums[1]小於等於6。因此,dp[1][6] = dp[0][6] | dp[0][1],這裡的dp[0][1]表示選取nums[1],再看看i = 0的選取方案,顯然當i = 0時,選取nums[0]使得j等於1

最後,dp[3][11]表示從陣列的[0,3]下標範圍內選取若干個正整數,是否存在一種選取方案使得被選取的正整數的和等於11

另一種方法:

遍歷陣列nums,遍歷的每個元素都選取。比如,遍歷nums[0]時選取nums[0],遍歷nums[1]時選取nums[1]

當遍歷nums[0]時,要使得j等於1dp[1] |= dp[0]

當遍歷nums[1]時,要使得j等於6dp[6] |= dp[1];要使得j等於5dp[5] |= dp[0]

注意到dp[6] |= dp[1],它表示選取nums[1],是否存在一種選取方案使得被選取的正整數的和等於1

public boolean canpartition(int nums) 

int sum = 0, maxnum = 0;

for (int num : nums)

if (sum % 2 != 0)

int target = sum / 2;

if (maxnum > target)

boolean dp = new boolean[target + 1];

dp[0] = true;

for (int i = 0; i < n; i++)

} return dp[target];

}

參考:

分割等和子集

給定乙個只包含正整數的非空陣列。是否可以將這個陣列分割成兩個子集,使得兩個子集的元素和相等。示例 1 輸入 1 5,11 5 輸出 true 解釋 陣列可以分割成 1,5,5 和 11 示例 2 輸入 1 2,3 5 輸出 false 解釋 陣列不能分割成兩個元素和相等的子集.思路 1.首先求陣列總...

分割等和子集

給定乙個只包含正整數的非空陣列。是否可以將這個陣列分割成兩個子集,使得兩個子集的元素和相等。注意 每個陣列中的元素不會超過 100 陣列的大小不會超過 200 示例 1 輸入 1,5,11,5 輸出 true 解釋 陣列可以分割成 1,5,5 和 11 示例 2 輸入 1,2,3,5 輸出 fals...

動態規劃 等和的分隔子集

題目 曉萌希望將1到n的連續整數組成的集合劃分成兩個子集合,且保證每個集合的數字和是相等。例如,對於n 3,對應的集合能被劃分成 和 兩個子集合.這兩個子集合中元素分別的和是相等的。對於n 3,我們只有一種劃分方法,而對於n 7時,我們將有4種劃分的方案。輸入包括一行,僅乙個整數,表示n的值 1 n...