如何找到两个序列之间的最小差异

时间:2017-12-04 02:35:00

标签: c++ optimization dynamic-programming

我的班级任务让我完全失去了如何实施。我在下面添加了问题。我不需要代码。我想就如何处理这个问题提出任何建议。我用谷歌搜索了它,但似乎找不到任何东西。

我的蛮力方法是遍历每一种可能性,并检查哪个子序列创建了最小值。这适用于小输入,但对于较大的输入显然太慢了。我还对值进行了预检,如果它们变得大于当前的最小值,我们就会将它们删除。

对于给定的序列a和b(不一定具有相同的长度),找到b的子序列a'或a和子序列b',使得diff(a',b')最小。归还差异。

差异是a [i] - b [i]的绝对值。为序列中的每个值添加这些差异以获得总计。目标是找到' b'它给出了它与' a'

的序列之间最小的总绝对差值

实施例: A = {1,2,6},b = {0,1,3,4,5},输出应为minimumDifference(a,b)= 2,其中最佳子序列为b'= {1,3 ,5}

要求

  1. 计算解决方案的最长时间为500毫秒(无论输入大小如何)。
  2. a的长度将在[3,1000]范围内。
  3. b的长度将在[a.length,1000]
  4. 的范围内
  5. 每个数组中的值将在[-1000,1000]
  6. 范围内
  7. 序列顺序很重要。无法排序

1 个答案:

答案 0 :(得分:0)

编辑2:我误解了问题最初,订单在这里很重要,因此我的解决方案实际上是不正确的。我现在更新了一个新的解决方案Idea(留下旧的解决方案供任何感兴趣的人参考)!

因此我们将DP[i][j]定义为A [1..i]和B [1..j]的两个子序列之间的最小差异。

现在让我们分别考虑它们a', b'的任何两个子序列。有4种情况:

  1. a'包含A[i]b'包含B[j]
  2. a'包含A[i]b'不包含B[j]
  3. a'不包含A[i]b'包含B[j]
  4. a'不包含A[i]b'不包含B[j]
  5. 1对应于重复DP[i-1][j-1]+|A[i]-B[j]|。 2对应于重复DP[i][j-1]。 3对应于重复DP[i-1][j],最后3对应于重复DP[i-1][j-1]

    由于我们想要所有这些场景中的最小值,我们有:

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

    此时间为O(n^2)。你能从这里建立吗?

    <强> OLD:

    这是子集和问题的变体。我们将Sum(a)称为a中所有元素的总和。所以我们可以按如下方式改写您的问题:

    给定一组A和一组B,我们理想地希望找到BSum(A)的子序列。如果我们找不到任何内容,我们希望找到总计B,......等Sum(A)-1的子序列。

    因此,您首先填写表SubsetSum(i,j),如果元素B[1..i]的子集总和为j,则为真,否则为false。填写整个表格。这需要O(nS)时间,其中n是元素数量,SA = Sum(A)的总和。

    接下来,从sum = Sum(A)开始。然后检查SubsetSum(n,sum),如果确实如此,则完成,其他方面,请尝试SubsetSum(n, sum-1),如果确实如此,那么您已完成,其他方面,请尝试{{1} }, ..., 等等。此步骤在SubsetSum(n, sum - 2)

    中运行

    这样,您可以最小化O(S)A子序列之间的差异。

    这在B中运行。

    这会让你入门吗?

    修改

    如果您还可以选择O(nS)的子序列,则可以定义A。然后拿出两张桌子:

    S=max(Sum(A), Sum(B))Subset-Sum-A(i,j)定义如上。

    然后设置Subset-Sum-B(i,j)并检查是否sum=S,如果不是,则检查Subset-Sum-A(n,sum) && Subset-Sum-B(n,sum),依此类推。