gfg https://practice.geeksforgeeks.org/problems/subset-sum-problem2014/1
密码 https://leetcode.com/problems/partition-equal-subset-sum/
问题: 给定大小为N的数组arr [],请检查是否可以将其分成两部分,以使两部分中的元素总和相同。
示例
输入:N = 4 arr = {1,5,11,5} 输出:是 说明: 这两个部分是{1、5、5}和{11}。
class Solution{
public:
static int equalPartition(int N, int arr[])
{
int sum = 0;
for (int i=0; i<N; i++)
sum += arr[i];
if (sum % 2 != 0)
return 0;
sum = sum/2;
int row = N+1;
int col = sum+1;
int dp[row][col];
for (int i=0; i<col; i++)
dp[0][i] = 0;
for (int i=0; i<row; i++)
dp[i][0] = 1;
for (int i=1; i<row; i++) {
for (int j=1; j<col; j++) {
if ( j< arr[i-1])
dp[i][j] = dp[i-1][j];
else{
if(j-arr[i-1] > 0){
dp[i][j] =max(dp[i-1][j], dp[i-1][j-arr[i-1]]);
}
else{
dp[i][j] = dp[i-1][j];
}
}
}
}
return dp[row-1][col-1];
}
};
答案 0 :(得分:1)
因此,出于好奇,我注册了门户网站以找出问题所在。我能够使用以下代码获得正确的答案。该代码稍作更改,主要是空间压缩。
我怀疑,N
(100)的约束和array
(1e5)中的值之和非常关键,会导致分割错误。
它也应该是j-arr[i-1] > 0
,而不是j-arr[i-1] >= 0
。
空间压缩的说明:
我们只需要第i-1
个状态即可计算当前状态i
的值,因此每个大小为sum
的2个数组就足够了。我保留了一个引用curr
来记住2个数组中的哪个被视为当前数组,而curr^1
将是前一个数组。我们可以进一步优化为仅大小为sum
的单个数组,但这超出了答案的范围。
int equalPartition(int N, int arr[])
{
int sum = 0;
for (int i=0; i<N; i++)
sum += arr[i];
if (sum % 2 != 0)
return 0;
sum = sum/2;
int row = N+1;
int col = sum+1;
int dp[2][col]; // change 1
for (int i=0; i<col; i++)
dp[0][i] = 0;
// for (int i=1; i<row; i++)
// dp[i][0] = 1;
dp[0][0] = 1; // change 2, due to space compression don't need above
int curr = 1; // change 3
for (int i=1; i<row; i++, curr^=1) { // change 4
for (int j=1; j<col; j++) {
dp[curr][j] = dp[curr^1][j]; // change 5
if(j-arr[curr^1] >= 0) // change 6
dp[curr][j] =max(dp[curr][j], dp[curr^1][j-arr[i-1]]); // change 7
}
}
return dp[curr^1][col-1]; // change 8
}
};