簡體   English   中英

最長共同遞增子序列動態規划

[英]Longest Common Increasing Subsequence Dynamic Programming

我正在努力尋找最長的共同增加子序列問題的解決方案。 如果您不熟悉,請點擊這里。 LCIS

該問題基本上可以簡化為兩個不同的問題。 “最長共同子序列”和“最長增加子序列”。 這是最長公共子序列的遞歸解決方案:

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;
}

基於此以及此處找到的一般遞歸公式我一直在嘗試實現算法,以便可以使用動態編程。

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;
}

顯然,這不能提供正確的解決方案。 任何幫助,將不勝感激。

例如,如果我給它兩個序列{1、2、4、5}和{12、1、2、4},則輸出為2。對於子序列{1,此處的正確輸出為3。 ,2,4}

編輯:

根據下面的建議,這是一些經過修改的代碼。 仍然不是100%正確。 但是更近。 請注意,我現在正在使用矢量,但這不應更改任何內容。

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;
}

請記住,您正在向后遍歷數組。 所以這個測試

 S[n] > S[prev]

應該相反:

 S[n] < S[prev]

我不確定為什么您需要上一個,因為它應該始終為n + 1,所以也許使用

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

如果您需要使其適合任何大小,則可以傳入該大小,或者只是標記說不要檢查n + 1

編輯:

我的錯誤-當n == 3 (或大小)時,您要經歷第一個if情況,因為您正處於(可能)增加的子序列的開始。

如果測試應該是

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

請注意,如果測試:

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

忽略了任一序列的第一個元素(並假設它位於遞增的子序列的末尾)。 在任一序列開始之前,您需要做的是停止遞歸。 您還知道,如果在序列開始之前走了,就不可能進入子序列,因此您可以為子序列的長度返回0。 所以測試應該是

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM