子集和 N 阵列解决方案,需要动态解决方案
SubSet sum with N array Solution, Dynamic Solution recquired
尽管您可以有任意数量的 array
,但让我们假设您有两个 array
{1,2,3,4,5,6} 和 {1,2,3 ,4,5,6}
你必须找出它们是否在两个 array
元素都参与的情况下总和为 4。即
1 from array1, 3 from array2
2 from array1, 2 from array2
3 from array1, 1 from array2
等等
在Nutshell:Want中实现子集求和算法,其中有两个数组,从两个数组中选择数组元素组成目标Sum
这里是 子集求和算法,我用的 array
bool subset_sum(int a[],int n, int sum)
{
bool dp[n+1][sum+1];
int i,j;
for(i=0;i<=n;i++)
dp[i][0]=true;
for(j=1;j<=sum;j++)
dp[0][j]=false;
for(i=1;i<=n;i++)
{
for(j=1;j<=sum;j++)
{
if(dp[i-1][j]==true)
dp[i][j]=true;
else
{
if(a[i-1]>j)
dp[i][j]=false;
else
dp[i][j]=dp[i-1][j-a[i-1]];
}
}
}
return dp[n][sum];
}
步骤,
find (Array1, Array2, N)
sort Array1
sort Array2
for (i -> 0 && i < Array1.length) and (j -> Array2.length-1 && j >= 0)
if(Array1[i] + Array2[j] == N)
return yes;
if(Array1[i] + Array2[j] > N)
j--;
else
i++;
return NO;
我们可以用 3 维 dp 来实现它。但为了简单和可读性,我使用两种方法编写它。
注意 :当我们从每个 array
中选择 至少一个元素 时,我的解决方案有效。如果存在我们必须从每个 array
中选择相同数量的元素的条件,则它不起作用。
// This is a helper method
// prevPosAr[] is the denotes what values could be made with participation from ALL
// arrays BEFORE the current array
// This method returns an array which denotes what values could be made with the
// with participation from ALL arrays UP TO current array
boolean[] getPossibleAr( boolean prevPossibleAr[], int ar[] )
{
boolean dp[][] = new boolean[ ar.length + 1 ][ prevPossibleAr.length ];
// dp[i][j] denotes if we can make value j using AT LEAST
// ONE element from current ar[0...i-1]
for (int i = 1; i <= ar.length; i++)
{
for (int j = 0; j < dp[i].length; j++)
{
if ( dp[i-1][j] == true )
{
// we can make value j using AT LEAST one element from ar[0...i-2]
// it implies that we can also make value j using AT LEAST
// one element from ar[0...i-1]
dp[i][j] = true;
continue;
}
int prev = i-ar[i-1];
// now we look behind
if ( prev < 0 )
{
// it implies that ar[i-1] > i
continue;
}
if ( prevPossibleAr[prev] || dp[i-1][prev] )
{
// It is the main catch
// Be careful
// if ( prevPossibleAr[prev] == true )
// it means that we could make the value prev
// using the previous arrays (without using any element
// of the current array)
// so now we can add ar[i-1] with prev and eventually make i
// if ( dp[i-1][prev] == true )
// it means that we could make prev using one or more
// elements from the current array....
// now we can add ar[i-1] with this and eventually make i
dp[i][j] = true;
}
}
}
// What is dp[ar.length] ?
// It is an array of booleans
// It denotes whether we can make value j using ALL the arrays
// (using means taking AT LEAST ONE ELEMENT)
// before the current array and using at least ONE element
// from the current array ar[0...ar.lengh-1] (That is the full current array)
return dp[ar.length];
}
// This is the method which will give us the output
boolean subsetSum(int ar[][], int sum )
{
boolean prevPossible[] = new boolean[sum+1];
prevPossible[0] = true;
for ( int i = 0; i < ar.length; i++ )
{
boolean newPossible[] = getPossibleAr(prevPossible, ar[i]);
// calling that helper function
// newPossible denotes what values can be made with
// participation from ALL arrays UP TO i th array
// (0 based index here)
prevPossible = newPossible;
}
return prevPossible[sum];
}
尽管您可以有任意数量的 array
,但让我们假设您有两个 array
{1,2,3,4,5,6} 和 {1,2,3 ,4,5,6}
你必须找出它们是否在两个 array
元素都参与的情况下总和为 4。即
1 from array1, 3 from array2
2 from array1, 2 from array2
3 from array1, 1 from array2
等等
在Nutshell:Want中实现子集求和算法,其中有两个数组,从两个数组中选择数组元素组成目标Sum
这里是 子集求和算法,我用的 array
bool subset_sum(int a[],int n, int sum)
{
bool dp[n+1][sum+1];
int i,j;
for(i=0;i<=n;i++)
dp[i][0]=true;
for(j=1;j<=sum;j++)
dp[0][j]=false;
for(i=1;i<=n;i++)
{
for(j=1;j<=sum;j++)
{
if(dp[i-1][j]==true)
dp[i][j]=true;
else
{
if(a[i-1]>j)
dp[i][j]=false;
else
dp[i][j]=dp[i-1][j-a[i-1]];
}
}
}
return dp[n][sum];
}
步骤,
find (Array1, Array2, N)
sort Array1
sort Array2
for (i -> 0 && i < Array1.length) and (j -> Array2.length-1 && j >= 0)
if(Array1[i] + Array2[j] == N)
return yes;
if(Array1[i] + Array2[j] > N)
j--;
else
i++;
return NO;
我们可以用 3 维 dp 来实现它。但为了简单和可读性,我使用两种方法编写它。
注意 :当我们从每个 array
中选择 至少一个元素 时,我的解决方案有效。如果存在我们必须从每个 array
中选择相同数量的元素的条件,则它不起作用。
// This is a helper method
// prevPosAr[] is the denotes what values could be made with participation from ALL
// arrays BEFORE the current array
// This method returns an array which denotes what values could be made with the
// with participation from ALL arrays UP TO current array
boolean[] getPossibleAr( boolean prevPossibleAr[], int ar[] )
{
boolean dp[][] = new boolean[ ar.length + 1 ][ prevPossibleAr.length ];
// dp[i][j] denotes if we can make value j using AT LEAST
// ONE element from current ar[0...i-1]
for (int i = 1; i <= ar.length; i++)
{
for (int j = 0; j < dp[i].length; j++)
{
if ( dp[i-1][j] == true )
{
// we can make value j using AT LEAST one element from ar[0...i-2]
// it implies that we can also make value j using AT LEAST
// one element from ar[0...i-1]
dp[i][j] = true;
continue;
}
int prev = i-ar[i-1];
// now we look behind
if ( prev < 0 )
{
// it implies that ar[i-1] > i
continue;
}
if ( prevPossibleAr[prev] || dp[i-1][prev] )
{
// It is the main catch
// Be careful
// if ( prevPossibleAr[prev] == true )
// it means that we could make the value prev
// using the previous arrays (without using any element
// of the current array)
// so now we can add ar[i-1] with prev and eventually make i
// if ( dp[i-1][prev] == true )
// it means that we could make prev using one or more
// elements from the current array....
// now we can add ar[i-1] with this and eventually make i
dp[i][j] = true;
}
}
}
// What is dp[ar.length] ?
// It is an array of booleans
// It denotes whether we can make value j using ALL the arrays
// (using means taking AT LEAST ONE ELEMENT)
// before the current array and using at least ONE element
// from the current array ar[0...ar.lengh-1] (That is the full current array)
return dp[ar.length];
}
// This is the method which will give us the output
boolean subsetSum(int ar[][], int sum )
{
boolean prevPossible[] = new boolean[sum+1];
prevPossible[0] = true;
for ( int i = 0; i < ar.length; i++ )
{
boolean newPossible[] = getPossibleAr(prevPossible, ar[i]);
// calling that helper function
// newPossible denotes what values can be made with
// participation from ALL arrays UP TO i th array
// (0 based index here)
prevPossible = newPossible;
}
return prevPossible[sum];
}