无法使用2d数组缓存将“自上而下的Memoization”方法应用于Subset Sum

时间:2018-03-24 18:21:04

标签: java

我正在尝试使用2d数组作为缓存来实现自上而下的Memoization方法来解决Subset-Sum问题。下面是我到目前为止尝试过的代码。但是我没有从代码中获得预期的结果。

public static void main(String []args){
       int set[] = {3, 34, 4, 12, 5, 2};
          int sum = 9;
          int n = set.length;
          if (isSubsetSum(set, n, sum) == true)
             System.out.println("Found a subset with given sum");
          else
             System.out.println("No subset with given sum");
     }

      static boolean isSubsetSum(int set[], int n, int sum){

         int[][] dp = new int[n][sum+1];

          for(int i = 0 ; i < n ; i++)
              for(int j = 0 ; j < sum ; j++)
                dp[i][j] = -1;



         for(int i = 0 ; i < n ; i++){
             dp[i][0] = 1;
         }

        return isSubsetSum1(set,n-1,sum,dp);
      }


      static boolean isSubsetSum1(int set[], int n, int sum,int[][] dp)
    {
       // Base Cases
       if (sum == 0)
         return true;
       if (n == 0 && sum != 0)
         return false;


       if(dp[n][sum] == -1){

           dp[n][sum] = isSubsetSum1(set, n-1, sum,dp) ? 1 : 0;

           if(sum > set[n-1]){
               boolean result  = isSubsetSum1(set, n-1, sum,dp) || 
                                   isSubsetSum1(set, n-1, sum-set[n-1],dp);
                dp[n][sum] = result ? 1 : 0;                

           }

       }


       return dp[n][sum] == 1 ? true : false;                               

    }

请帮助我找到代码中的逻辑错误。

1 个答案:

答案 0 :(得分:0)

您可以尝试一种不需要递归的动态编程解决方案。基本上你必须根据一些合同建立一个带有回顾的矩阵(2d数组缓存)。

我试图用Kotlin解决问题,找出你给出整数数组的子集组合数。它在2 3 4 5 12 34的情况下产生一个矩阵,告诉你每个预期数量有多少组合。预期的数字位于最左侧列的下方示例中:

   2 3 4 5 1234
0  1 1 1 1 1 1 
1  0 0 0 0 0 0 
2  1 1 1 1 1 1 
3  0 1 1 1 1 1 
4  0 0 1 1 1 1 
5  0 1 1 2 2 **2** 
6  0 0 1 1 1 1 
7  0 0 1 2 2 2 
8  0 0 0 1 1 **1** 
9  0 0 1 2 2 **2** 

如果您阅读此表,它会告诉您,对于5的总和,给定完整数组(2 3 4 5 12 34),您有2个子集,8个只有1个,9个2个,等等。这些示例在上面突出显示

您可以使用此Kotlin代码构建此数组:

fun subsetTable(coinsA: IntArray, total: Int): Array<IntArray> {
    val coins = coinsA.sorted()
    val size = coins.size
    val table = Array(total + 1, { IntArray(size) })
    (0 until size).forEach { table[0][it] = 1 }
    (1..total).forEach { row ->
        (0 until coins.size).forEach { col ->
            if (col == 0) {
                table[row][col] = if (row == coins[0]) 1 else 0
            } else {
                val x = if (row - coins[col] >= 0) table[row - coins[col]][col - 1] else 0
                val y = if (col >= 1) table[row][col - 1] else 0
                table[row][col] = x + y
            }
        }
    }
    return table
}

免责声明:我没有广泛测试代码,因此可能存在一些问题。

如果您有兴趣,我可以将此代码转换为Java。