[英]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.