简体   繁体   English

最长共同递增子序列动态规划

[英]Longest Common Increasing Subsequence Dynamic Programming

I'm working on finding a solution to the longest common increasing sub sequence problem. 我正在努力寻找最长的共同增加子序列问题的解决方案。 Here's a link if you're not familiar with it. 如果您不熟悉,请点击这里。 LCIS LCIS

The problem can basically be reduced to two different problems. 该问题基本上可以简化为两个不同的问题。 'Longest common subsequence' and 'Longest increasing subsequence'. “最长共同子序列”和“最长增加子序列”。 Here's the recursive solution to Longest common subsequence: 这是最长公共子序列的递归解决方案:

LCS(S,n,T,m)
{
if (n==0 || m==0) return 0;
if (S[n] == T[m]) result = 1 + LCS(S,n-1,T,m-1); // no harm in matching up
else result = max( LCS(S,n-1,T,m), LCS(S,n,T,m-1) );
return result;
}

Based on that and the general recursive formula found here I've been trying to implement the algorithm so I can use dynamic programming. 基于此以及此处找到的一般递归公式我一直在尝试实现算法,以便可以使用动态编程。

int lcis(int S[4], int n, int T[4], int m, int prev)
{
  int result;

  if (n == 0 || m  == 0)
    return 1;
  if (S[n] == T[m] && S[n] > S[prev]){
    result = myMax(1 + lcis(S, n-1, T, m-1, n), lcis(S, n-1, T, m, prev),
                    lcis(S, n, T, m-1, prev)) ;
  }
  else
    result = max(lcis(S,n-1,T,m, prev), lcis(S,n,T,m-1, prev));

  return result;
}

Obviously this does not give the correct solution. 显然,这不能提供正确的解决方案。 Any help would be appreciated. 任何帮助,将不胜感激。

For example, if I give it the two sequences {1, 2, 4, 5} and {12, 1, 2, 4} I get an output of 2. The correct output here would be 3, for the sub sequence {1,2,4} 例如,如果我给它两个序列{1、2、4、5}和{12、1、2、4},则输出为2。对于子序列{1,此处的正确输出为3。 ,2,4}

EDIT: 编辑:

Here is some revised code, after suggestions from below. 根据下面的建议,这是一些经过修改的代码。 Still not 100% correct. 仍然不是100%正确。 But closer. 但是更近。 Note I am now using vectors, but this shouldn't change anything. 请注意,我现在正在使用矢量,但这不应更改任何内容。

int lcis(vector<int> S, int n, vector<int> T, int m, int size)
{
  int result;

  if (n < 0 || m < 0)
    return 0;
  if (S[n] == T[m] && (n == size - 1 || S[n] < S[n + 1] )){
    result = myMax(1 + lcis(S, n - 1, T, m - 1, size), lcis(S, n - 1, T, m, size),
                    lcis(S, n, T, m - 1, size));
  }
  else
    result = max(lcis(S, n-1, T, m, size), lcis(S, n, T, m-1, size));

  return result;
}

Remember that you are going backward through the array. 请记住,您正在向后遍历数组。 So this test 所以这个测试

 S[n] > S[prev]

Should be the other way around: 应该相反:

 S[n] < S[prev]

I am not sure why you need prev at all, as it should always be n+1, so maybe use 我不确定为什么您需要上一个,因为它应该始终为n + 1,所以也许使用

if (S[n] == T[m] && n < 3 && S[n] < S[n+1])

If you need to make it work for any size, then either pass the size in, or just a flag to say don't check n+1 如果您需要使其适合任何大小,则可以传入该大小,或者只是标记说不要检查n + 1

Edit: 编辑:

My mistake - you want to be going through the first if case when n == 3 (or size), as you are at the start of a (potentially) increasing subsequence. 我的错误-当n == 3 (或大小)时,您要经历第一个if情况,因为您正处于(可能)增加的子序列的开始。

The if test should be 如果测试应该是

if (S[n] == T[m] && (n == 3 || S[n] < S[n+1]))

Note that this if test: 请注意,如果测试:

if (n == 0 || m  == 0)
    return 1;

is ignoring the first element of either sequence (and assuming it is at the end of an increasing subsequence). 忽略了任一序列的第一个元素(并假设它位于递增的子序列的末尾)。 What is needed is to stop the recursion when you have gone before the start of either sequence. 在任一序列开始之前,您需要做的是停止递归。 You also know that when you have gone before the start of the sequence, you can't possibly be in a subsequence, so you can return 0 for the length of the subsequence. 您还知道,如果在序列开始之前走了,就不可能进入子序列,因此您可以为子序列的长度返回0。 So the test should be 所以测试应该是

if (n < 0 || m < 0)
    return 0;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM