動態規劃之最長遞增子串行

2021-07-15 04:06:11 字數 2670 閱讀 8805

面試經常出現問題:

最長遞增子串行問題是乙個很基本、較常見的小問題,但這個問題的求解方法卻並不那麼顯而易見,需要較深入的思考和較好的演算法素養才能得出良好的演算法。由於這個問題能運用學過的基本的演算法分析和設計的方法與思想,能夠鍛鍊設計較複雜演算法的思維,我對這個問題進行了較深入的分析思考,得出了幾種複雜度不同演算法,並給出了分析和證明。 一,

最長遞增子串行問題的描述

設l=<

a1,a2,…,an

>是n個不同的實數的序列,l的遞增子串行是這樣乙個子串行lin=<

ak1,ak2,…,akm

>

,其中k1

2<…m

且ak1

k2<…km

。求最大的m值。

二,第一種演算法:轉化為lcs問題求解

設序列x=<

b1,b2,…,bn

>是對序列l=<

a1,a2,…,an

>按遞增排好序的序列。那麼顯然x與l的最長公共子串行即為l的最長遞增子串行。這樣就把求最長遞增子串行的問題轉化為求最長公共子串行問題lcs了。

最長公共子串行問題用動態規劃的演算法可解。設li=<

a1,a2,…,ai

>,xj=<

b1,b2,…,bj

>,它們分別為l和x的子串行。令c[i,j]為li與xj的最長公共子串行的長度。

這可以用時間複雜度為o(

n2)的演算法求解,由於這個演算法上課時講過,所以具體**在此略去。求最長遞增子串行的演算法時間複雜度由排序所用的o(nlogn)的時間加上求lcs的o(

n2)的時間,演算法的最壞時間複雜度為o(nlogn)+o(

n2)=o(

n2)。 三,

第二種演算法:動態規劃法

設f(i)表示l中以

ai為末元素的最長遞增子串行的長度。則有如下的遞推方程:

這個遞推方程的意思是,在求以

ai為末元素的最長遞增子串行時,找到所有序號在l前面且小於

ai的元素

aj,即jaji

。如果這樣的元素存在,那麼對所有

aj,都有乙個以

aj為末元素的最長遞增子串行的長度f(j),把其中最大的f(j)選出來,那麼f(i)就等於最大的f(j)加上1,即以ai

為末元素的最長遞增子串行,等於以使f(j)最大的那個

aj為末元素的遞增子串行最末再加上

ai;如果這樣的元素不存在,那麼

ai自身構成乙個長度為1的以

ai為末元素的遞增子串行。

//動態規劃之最長遞增子串行

#include #include #include #include using namespace std;

int longestincsub(vector& vec,int length)

} int max = 0;

for (int i = 0; i < len; i++)

return max;

}//整數處理

int lcs_length_int(vector& vec1, vector& vec2, int c[100], int b[100])

else if (c[i - 1][j] >= c[i][j - 1])

else

/*cout << "計算最優值效果圖如下所示:" << endl;

for (int i = 0; i <= m; i++)

cout << endl;

}*/return c[m][n];

}int main();

int length[100] = ;

cout << longestincsub(vec1,length) << endl;

int c[100][100] = ;

int b[100][100] = ;

vectorvec2(vec1.begin(), vec1.end());

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

cout << lcs_length_int(vec1, vec2, c, b) << endl;

system("pause");

return 0;

}

使用二分查詢進行優化

/* *問題:求陣列中最長遞增子串行

*寫乙個時間複雜度盡可能低的程式,求乙個一維陣列(n個元素)中的最長遞增子串行的長度。

*例如:在序列1,-1,2,-3,4,-5,6,-7中,其最長的遞增子串行為1,2,4,6,最長遞增子串行

*的長度為4。

*求解思路:使用動態規劃+二分查詢演算法 時間複雜度o(nlog(n))

*/

#include #include using namespace std;

int lis(int *array,int len)

lis[left] = array[i];//插入

if(left > max)

} delete lis;

return max;

}

int main(int args,char **argv)

; int len = sizeof(array)/sizeof(int);

int res = lis(array,len);

cout<

動態規劃之最長遞增子串行

基本歸納法 對於ai 1,只要考察其前乙個狀態ai即可完成整個推理過程,它的特點是只要ai確定,則計算ai 1便不需要考察前序狀態a0.ai 1,我們將這一模型稱之為馬爾科夫模型 高階歸納法 相應的,對於ai 1,考察前i個狀態集才可完成整個推理過程,往往稱之為高階馬爾科夫模型 在計算機演算法中,高...

動態規劃之最長遞增子串行

1 問題描述 給定乙個序列arr,假設全是整數,給出最長的乙個遞增子串行,比如輸入arr 2,1,5,3,6,4,8,9,7 輸出 1,3,4,8,9 4 下面是 include includeusing namespace std int main 首先計算出以第i個位置結尾的最長遞增子串行的大小...

動態規劃之最長遞增子串行LIS

子串行 乙個序列 s 任意刪除若干項,剩餘的序列叫做s的乙個子串行。也可以認為是從序列s按原順序保留任意若干項得到的序列。現在我們要求解乙個陣列裡最長遞增子串行的長度。在此我提出兩種方法,並且附上 解決方法 1 利用動態規劃求解兩個陣列的最長哦公共子串行來求解這種題目,但只適用於求解最長遞增子串行的...