DP:最长的后续思想过程&溶液

时间:2016-06-09 05:20:37

标签: c++ algorithm time-complexity dynamic-programming

对于Longest Increasing Subsequence问题,我设想保持一个DP阵列始终按顺序将最大值保持在最远端。看起来像这样的东西:

{1, 1, 2, 3, 3, 4, 5, 6, 6, 6}

我生成第一个不正确的解决方案时所遵循的思维过程是,我们想要查看整个数组,仅从第一个元素开始,计算LIS,然后逐步将值添加到数组的末尾。在执行此操作时,我们将DP阵列中的LIS递增计算为旧子阵列的LIS以及我们添加的新元素。这意味着i数组的索引dp存在长度为i的子数组的LCS值。

更明确地说

array => {5, 6, 7, 1, 2, 3, 4}
dp    => {1, 2, 3, 3, 3, 3, 4}

这样,DP阵列的最后一个条目将是当前阵列的LIS。这将作为我们的不变量,所以当我们结束时,我们可以确信最后一个值是我们唯一需要的值。然后我突然意识到,当我们遍历具有DP类型感觉的数组时,下一个值不依赖于数组中任何先前列表的值,因此此方法与维护maxLIS相同变量,我在许多O(n)解决方案中看到的模式。所以我最接近正确的解决方案如下:

1。)将输入数组/向量的副本保存为old

2.)对原始输入数组进行排序

3。)遍历排序后的数组,每当下一个值(应该大于当前值)出现在原始数组中的当前值之前,将变量longest递增1。

4.)返回longest

代码将是〜:

int lengthOfLIS(vector<int>& seq) {
  if (!seq.size()) return 0;
  vector<int> old = seq;

  sort(seq.begin(), seq.end());

  int longest = 1;

  for (int i = 1; i < seq.size(); ++i) {
    if (seq[i] > seq[i-1] && find(old.begin(), old.end(), seq[i]) - old.begin() > find(old.begin(), old.end(), seq[i-1]) - old.begin()) longest++;
  }
  return longest;
}

我们有find方法(我假设是线性运算)我们可以通过创建一个数据结构来存储值的原始索引以及值本身来进行常量操作,这样我们就可以了不必进行任何遍历来查找原始数组(old)中元素的索引。我相信这将是一个O(nlog(n))解决方案但是使用此输入数组失败:[1,3,6,7,9,4,10,5,6]CHECK HERE

最后我做了一些研究,我发现我读过的所有解决方案指南都隐藏在这样一个事实中,即他们的解决方案保持其DP数组的值不按顺序,而是像这样:DP数组中的值表示长度子序列的最后一个值是originalArray[index]的值的增加子序列。

更清楚地说,

array => {5, 6, 7, 1, 2, 3}
dp    => {1, 2, 3, 1, 2, 3}

这里,其中5是增加子序列的最后一个值,没有值在它之前,所以它必须是长度1.如果6是增加子序列的最后一个值,我们必须在它之前查看所有值以6结尾的子序列可以有多长。在它之前只能有5个,因此到目前为止,这是最长的增加子序列2.这将继续,并且您将返回DP阵列中的最大值。此解决方案的时间复杂度为O(n^2),标准天真解决方案。

问题:

我很好奇如何正确地思考这个问题。我想微调我的思维过程,以便我能从头开始提出最佳解决方案(这至少是目标),所以我想知道

1。)这个问题的哪些属性应该触发我使用DP阵列的方式与我使用它的方式不同?事后看来,我原来的方式只相当于保留一个最大变量,但即使这样我也很难看到这个问题的属性会触发思想嘿,我的DP数组中索引i的一个条目的值应该是越来越多的子序列以originalArray [i]结尾。我很难看到我应该怎么想出来。

2.。)是否有可能让我提议的O(nlog(n))解决方案起作用?我知道存在一个O(nlog(n))解决方案,但由于我不能让我的工作,我认为我需要在正确的方向上轻推。

1 个答案:

答案 0 :(得分:0)

我承认,这是一个有趣的问题,我没有确切的答案,但我想我可以给你一个正确方向的推动。所以这就是:

面对这样的困境,我通常会转向基础知识。与您的情况一样,请查看动态编程的定义。它有两个属性:

  
      
  1. 重叠子问题
  2.   
  3. 最佳子结构。
  4.   

您可以轻松找到这些属性反映在标准解决方案中,但不是您的。您可以在cormen中了解这些内容,或者只是在DP的上下文中进行搜索。

在我看来,你的解决方案不是DP,你只是发现了一些模式而你正试图根据这种模式来解决。如果您没有得到解决方案,则意味着您的模式错误或您的解决方案忽略了某些内容。在这种情况下,尝试以数学方式证明您正在观察的模式是正确的,并证明解决方案也应该有效。

给我一​​些时间,虽然我会通过你的解决方案,但你也可以尝试为你的解决方案开发证据。