【问题标题】:Use dynamic programming to find a subset of numbers whose sum is closest to given number M使用动态规划找到总和最接近给定数字 M 的数字子集
【发布时间】:2015-11-15 06:47:11
【问题描述】:

给定一个由 n 个正整数 a1、a2、... a3 组成的集合 A 和另一个正整数 M,我将找到 A 的一个数的子集,其和最接近 M。换句话说,我' m 试图找到 A 的子集 A' 使得绝对值 |M - ???? Σ a∈A′|被最小化,其中 [ Σ a∈A' a ] 是 A' 的个数的总和。我只需要返回解子集A'的元素之和,而不报告实际的子集A'。

例如,如果我们有 A 为 {1, 4, 7, 12} 并且 M = 15。那么,解子集是 A′ = {4, 12},因此算法只需要返回 4 + 12 = 16 作为答案。

该问题的动态规划算法应该在 最坏情况下的 O(nK) 时间,其中 K 是所有 A 数的总和。

【问题讨论】:

    标签: dynamic-programming knapsack-problem subset-sum


    【解决方案1】:

    你构建一个大小为 n*K 的动态规划表,其中

    D[i][j] = Can you get sum j using the first i elements ?

    您可以使用的递归关系是:D[i][j] = D[i-1][j-a[i]] OR D[i-1][j] 如果您认为可以添加或离开第 i 个元素,则可以导出此关系。

    时间复杂度:O(nK) 其中 K=所有元素的总和

    最后,您迭代整个可能的总和,即 D[n][j] for j=1..K。最接近 M 的将是您的答案。

    【讨论】:

      【解决方案2】:

      对于动态算法,我们

      1. 定义我们将致力于的价值

      这里的值集实际上是一个表格。

      对于这个问题,我们定义值 DP[i , j] 作为我们是否可以使用前 i 个元素获得和 j 的指标。 (1 表示是,0 表示否)

      这里0

      1. 定义递归关系

      DP[i+1 , j] = 1 , if ( DP[i,j] == 1 || DP[i,j-A[i+1]] ==1)

      否则,DP[i+1, j] = 0。

      不要忘记首先将表初始化为 0。这解决了边界和平凡的情况。

      1. 计算你想要的值

        通过自底向上的实现,最终可以填满整个表格。

      现在,事情变得容易了。只需要在表中找出最接近 M 且值为 1 的值即可。

      在这里,只需处理 DP[n][j],因为 n 涵盖了整个集合。找到最接近 M 且值为 1 的 j。

      时间复杂度为 O(kn),因为您总共迭代了 k*n 次。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-08-09
        • 2021-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多