【问题标题】:subset sum through DP通过 DP 的子集和
【发布时间】:2015-02-18 13:44:38
【问题描述】:

http://comproguide.blogspot.in/2013/10/subset-sum-problem.html
对此方法有一个简明的解释 但是,我通过一个小练习来列举这个算法,以找到 {1,2,3,4} 中总和为 4 的子集。

我注意到单元格 {1,1},{2,2} 返回 false。

我的逻辑理解错了吗?
还是该算法不认为该集合是其自身的子集?

我原以为 {1,1} 会返回一个真值,因为 1 相加。

【问题讨论】:

  • 我认为它不会两次使用相同的值。虽然我想知道为什么您认为 {1,1} 会返回 true,因为它的总和不是 4 而 {2,2} 不会,因为它只能使用 2 一次。
  • 矩阵[i][j] = true;表示存在数组 [0..j-1] 的子集,其中包含总和 i.....这意味着 {1,1} 表示总和为 1 的子集 - 或者不是这样?
  • 总和不是 i。在示例中,它查找 sum = 100 然后 sum = 200 的子集。矩阵示例仅返回 true 或 false,因为它使用布尔表达式,在本例中,100 为 false,200 为 true。子集可以包含超过 2 个值,例如加起来 200 {37, 62, 101}

标签: java algorithm dynamic-programming


【解决方案1】:

{1} 应该算作总和为 1 的子集。我已在程序中添加了一些输出以显示表格:

public class SubsetSum {
    public static void main(String[] args) {
        int [] array = { 1, 2, 3, 4 };
        hasSum(array, 4);
    }

    public static boolean hasSum(int [] array, int sum) {
        int len = array.length;
        boolean[][] table = new boolean[sum+1][len+1];
        for(int i = 0; i <= len; i++) table[0][i] = true;
        for(int i = 1; i <= sum; i++) table[i][0] = false;
        for(int 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];
                }
            }
        }

        System.out.printf("%10s ", "-");
        for(int i = 0; i <= sum; i++) {
            System.out.printf("%10s ", i);
        }
        System.out.println();
        for(int j = 0; j <= len; j++) {
            System.out.printf("%10s ", j);
            for(int i = 0; i <= sum; i++) {
                System.out.printf("%10s ", table[i][j]);
            }
            System.out.println();
        }

        return table[sum][len];
    }
}

输出:

     -          0          1          2          3          4 
     0       true      false      false      false      false 
     1       true       true      false      false      false 
     2       true       true       true       true      false 
     3       true       true       true       true       true 
     4       true       true       true       true       true 

这些结果看起来是正确的。我会解释一些值,例如:

  • table[0][0] 为真,因为 {} 总和为 0
  • table[1][1] 为真,因为 {1} 总和为 1
  • table[2][2] 为真,因为 {2} 总和为 2
  • table[3][2] 为真,因为 {1,2} 总和为 3
  • table[4][3] 为真,因为 {1,3} 总和为 4

【讨论】:

    【解决方案2】:

    我是这篇文章的作者。 @fgb 显示的输出看起来是正确的。我没有看到代码有任何问题。我的解释有什么问题吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-21
      • 1970-01-01
      • 2014-07-16
      • 2014-05-23
      • 2016-07-02
      • 1970-01-01
      相关资源
      最近更新 更多