4

I have been learning dynamic programming, and I want to take the classic subset sum problem a little further by printing out all the subsets which add up to a number. How exactly would I go about doing this? As of now, I know how to print true or false based on whether there is a subset that adds up to it

    public static boolean hasSum(int [] array, int sum)
{
    int len = array.length;
    boolean[][] table = new boolean[sum+1][len+1];

    int i;

    for( i = 0; i <= len; i++ )
        table[0][i] = true;

    for( i = 1; i <= sum; i++ )
        table[i][0] = false;

    for( i = 1; i <= sum; i++ )
    {
        for( int j = 1; j <= len; j++ )
        {
            table[i][j] = table[i][j-1]; 

            if( !table[i][j] && i >= array[j-1] )
                table[i][j] = table[i-array[j-1]][j-1];
        }
    }        

    return table[sum][len];
}

if possible, I'd like to return an array of all of the subsets.

seanscal
  • 568
  • 2
  • 9
  • 33

1 Answers1

1

This problem is harder than the original one.

For each table[i][j] which you set to true, you have to mark all its predecessors i.e. all the table[i1][j1]=true, due to which you marked table[i][j] as true. This way you build a kind of graph structure. The vertices of this graph are couples (i,j).

Then when you want to print the answer, you have to trace back from (i,j) to all possible (i1,j1) and so on going backwards. For this, just an array won't be enough, you'll need additional/helper data structures.

peter.petrov
  • 38,363
  • 16
  • 94
  • 159
  • yeah thats what I was thinking. In each index of the table, would I then store the last number? So that to add up to say, 10 for {2,4,5,6,8,1), I could take the 1 as it was last to 10, then the 5 as it was last to 9 with the 4, and then the 4 from adding to 4, making it [4,5,1]? I hope thats clear – seanscal Dec 15 '15 at 20:05