当前位置: 首页 > 知识库问答 >
问题:

动态规划子集算法

苏培
2023-03-14

我正在为动态编程编写一些复习材料。我需要提出如何划分子问题,计算出基本情况,并提出递归公式。

给定 n 个正整数 a1,a2,...,an、一个数字 k 和一个目标 W,我们希望选择一个子集 T,其总和恰好是 k 个元素,其总和最接近 W。每个元素只能选择一次。定义一个具有 3 个参数的子问题(即 C[x,y,z] = ...)。

我只处理过几个动态编程示例,从未处理过定义子问题时需要3个参数的示例。我在这里真的迷路了。如果有人能发光,那就太好了。

我对子问题的最佳猜测是:

c[x, y, z]={a1,… ay}中的x个元素,其中总和正好是z

但我不知道这是否正确。

共有2个答案

宣望
2023-03-14

在这种情况下,我将让C(x, y, z)是一个布尔值,表示是否可以使用{a1… ax}中的y精确地求和z。

尽管这不是完全相同的问题,但维基百科为各种类似问题提供了动态编程解决方案,并提供了解释。也许这会给你一些想法。

诸葛苏燕
2023-03-14

将其分解为三个参数的一种方法是:

x: maximum index of item considered for inclusion in subset
n: number of items in subset
s: sum of subset

基本情况是C[0,0,0]=真,C[0,i

递归情况为:

C[i,n+1,s+a_i] = C[i-1,n,s]  // use item i
C[i,n,s] = C[i-1,n,s] // dont use item i

这使用了空间O(n^2 * max(a_i))(可以通过在使用时丢弃C[i,,]来减少到O(n*max(a_i))

然后只需在z附近搜索C[n,I,j]寻找j就能得到最终答案。

作为循环...

for (int i = 1; i <= n; i++)
{
    C[i,n+1,s+a_i] ||= C[i-1,n,s];
    C[i,n,s] ||= C[i-1,n,s];
}

作为递归函数:

bool C(int maxindex, int size, int sum)
{
    if (memoize(maxindex, size, sum))
         return cached;

    if (maxindex == 0)
        return (size == 0 && sum == 0);

    return
         C(maxindex-1, size-1, sum - A[maxindex]) ||  // version using A[maxindex]
         C(maxindex-1, size, sum); // version not using A[maxindex]
}
 类似资料:
  • 我有一个子集问题的工作代码,如果它发现一个子集等于所需的目标,它可以打印数字。 > 我想打印给定目标的所有可能的子集,我不知道要为此更改什么。 我如何让它对负数起作用?

  • 给定一个数组,是否可以从起始索引开始选择一组整数,这样该组就与给定的目标相加?但是,附加的限制是必须选择所有的6。 groupSum6(0,[5,6,2],8)true groupSum6(0,[5,6,2],9)false groupSum6(0,[5,6,2],7)false 只是想弄清楚我错在哪里。声明nums[start]==6的特殊情况是不是错误的方法?

  • 我正在练习动态编程,我正在努力调试我的代码。这个想法是在给定一组数字的情况下找出求和是否可能。这是我的代码: 以下是输出: 据我所知,在我的fe语句中,算法应该向上1行,然后查看x和y的差异并检查该槽是否可能。例如,在最明显的情况下,最后一行的最后一个元素。那将是10(y)-11(x),它应该一直回到它上面一行的索引1,我们知道这是True。不完全确定我做错了什么,如果能帮助理解这一点,将不胜感激

  • 主要内容:动态规划算法的实际应用动态规划算法解决问题的过程和分治算法类似,也是先将问题拆分成多个简单的小问题,通过逐一解决这些小问题找到整个问题的答案。不同之处在于,分治算法拆分出的小问题之间是相互独立的,而动态规划算法拆分出的小问题之间相互关联,例如要想解决问题 A,必须先解决问题 B 和 C。 《贪心算法》一节中,给大家举过一个例子,假设有 1、7、10 这 3 种面值的纸币,每种纸币使用的数量不限,要求用尽可能少的纸币拼凑

  • 我目前正在学习动态编程,我无法解决这个问题。有人能给我一个算法吗?:考虑一个有向图G=(V,E),其中每个边都标有一个字母Sigma的字符,我们指定一个特殊的顶点s作为开始顶点,另一个f作为最后顶点。我们说G接受一个字符串a=a1a2。如果有一条从s到f的n条边的路径,其标号拼写为序列a。设计了一个O((V+E)n)动态规划算法来确定a是否被G接受。

  • 我无法弄清楚重叠子问题的DP第一属性在哪里适合子集和问题。然而,我理解最优子结构部分。在执行包含和排除元素的递归解决方案时,问题在哪里重叠 是不是因为这是一个NP问题,所以没有DP的两个性质 问题的链接是http://www.geeksforgeeks.org/dynamic-programming-subset-sum-problem/ 有人能帮助我理解这一点吗。