【问题标题】:How is this solution an example of dynamic programming?该解决方案如何成为动态规划的示例?
【发布时间】:2011-05-25 14:48:07
【问题描述】:

一位讲师在课堂上提出了这个问题: [问题]

n 个整数的序列存储在 一个数组 A[1..n]。 A 中的整数 a 是 如果出现更多,则称为多数 比 A 中的 n/2 倍。

可以设计一个 O(n) 算法来 找到大多数基于 以下观察:如果两个 原著中的不同元素 序列被删除,然后 原始序列中的多数 仍然是新的多数 顺序。使用这个观察,或 否则,将编程代码写入 找到大多数,如果存在的话,在 O(n) 时间。

接受此解决方案的 [解决方案]

int findCandidate(int[] a)
{
    int maj_index = 0;
    int count = 1;
    for (int i=1;i<a.length;i++)
    {
        if (a[maj_index] == a[i])
            count++;
        else
            count--;

        if (count == 0)
        {
            maj_index =i;
            count++;
        }
    }
    return a[maj_index];
}

int findMajority(int[] a)
{
    int c = findCandidate(a);
    int count = 0;
    for (int i=0;i<a.length;i++)
        if (a[i] == c) count++;

    if (count > n/2) return c;
    return -1;//just a marker - no majority found
}

我看不出所提供的解决方案如何是动态解决方案。而且我看不出他是如何根据措辞将代码提取出来的。

【问题讨论】:

  • 这个问题比较笼统。包括你为什么它不是一个动态的解决方案来给人们一些回应的理由。
  • 这不是动态编程。而且我没有看到任何人(包括你的教授)说它是,除了你的问题的标题。
  • 基思,我的教授说它是动态的,我没有从互联网以太中提取问题(和解决方案)。

标签: algorithm dynamic-programming


【解决方案1】:

origin of the term dynamic programming 试图描述一种优化某些解决方案的非常棒的方法(使用动态的,因为它听起来更有力)。换句话说,当你看到“动态编程”时,你需要把它翻译成“很棒的优化”。

【讨论】:

    【解决方案2】:

    'Dynamic programming' 与动态分配内存或其他无关,它只是一个旧术语。事实上,它也与“编程”的现代含义无关。

    这是一种解决特定类别问题的方法 - 当子问题的最优解被保证是更大问题的最优解的一部分时。例如,如果您想用最少的账单支付 567 美元,则该解决方案将包含至少一种 1..566 美元的解决方案和一张其他账单。

    代码只是算法的一个应用。

    【讨论】:

      【解决方案3】:

      这是动态编程,因为 findCandidate 函数将提供的数组分解为更小、更易于管理的部分。在这种情况下,他从第一个数组开始作为多数人的候选人。通过在遇到计数时增加计数并在遇到计数时减少计数,他确定这是否为真。当计数为零时,我们知道前 i 个字符没有多数。通过不断地计算局部多数,我们不需要在候选识别阶段多次遍历数组。然后,我们通过第二次遍历数组来检查该候选人是否实际上是多数,给我们 O(n)。它实际上运行了 2n 次,因为我们迭代了两次,但常数无关紧要。

      【讨论】:

      • “将问题分解为更小的子问题”是分治法的定义,对于动态编程来说甚至远远不够。为了成为动态编程,它还必须记住子问题的解决方案,并且能够在先前解决的子问题重新出现时检索记忆的解决方案(这样子问题就不会被解决多次)。在这个算法中它是相当不明显的......我想知道它是否真的是动态编程的一个很好的例子(如果有的话)。
      • 我同意安德烈的观点。 DP的一个特点是动态部分消耗存储。例如,这可以是记忆或查找表。我在这里看不到任何动态
      • "将问题实例划分为若干个子实例(大多数情况下为2个),递归地分别求解每个子实例,然后将子实例的解组合得到原问题的解..." -阿尔苏维耶尔。根据这个定义,我不能说上面给出的解决方案是分而治之。
      • 同意欧文。根据维基百科:“动态编程是一种通过将复杂问题分解为更简单的子问题来解决复杂问题的方法。”据我估计,这个算法正是这样做的。
      • @WadeTandy 确实,DP 在分而治之背后使用递归和逻辑并没有错,毕竟在考虑重叠子问题时,我们将考虑如何划分原始问题。然而,正如 AnreyT 正确指出的那样,DP 涉及某种记忆/查找表。 Btw D&C 和 DP 差异的最佳解释在这里:stackoverflow.com/questions/13538459/…
      猜你喜欢
      • 1970-01-01
      • 2014-09-09
      • 1970-01-01
      • 1970-01-01
      • 2015-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多