問題:
求乙個一維陣列中最長遞增子串行的長度。
解法1:
非常明顯用動態規劃的演算法,選取以下的階段(這樣的選法極為常見),可使階段間的關係具有無後效性。
階段:在全部以元素k結尾的子陣列中,選出當中的最長遞增子串行,k=1,2...n。
狀態:以元素k結尾的最長遞增子串行中僅僅有乙個最長的遞增子串行。
決策:決定元素k結尾的最長遞增子串行有k-1種獲取的途徑,前面以不論什麼乙個元素結尾的最長遞增子串行都可能成為其的一部分。
這種時間複雜度為o(n^2),空間複雜度為o(n)
解法2:
動態規劃的時間複雜度一般與空間複雜度同樣,由於決定下乙個階段的全部條件我們已儲存到dp中,在處理過程中我們能夠對已得到的這些條件進行處理來減少時間複雜度。而這裡時間複雜度竟比空間複雜度高了o(n),說明還有能夠繼續優化的空間。
我們能夠統計前面全部階段的最長遞增子串行的長度,將長度同樣的最長遞增子串行分到同一組中,並僅僅記錄它們最大元素的最小值maxv[長度值],假設階段k的元素大於長度為i最長遞增子串行的這個最小值maxv[i],那麼階段k的最長遞增子串行的長度至少為i+1。
而我們發現統計出的maxv陣列具有非常好的遞增關係(動態規劃都是用來解決最優化問題,我們總能通過優化關係對之前統計出的結果進行排序),即假設i
證明:反證法,如果當i=maxv[j],那麼存在乙個長度為i的遞增序列a1a2...ai,且ai是計算到階段k時全部長度為i的遞增序列中最大元素的最小值,以及長度為j的序列b1b2...bj且ai>=bj,因為i
**:#include#include#include#define max 1000
using namespace std;
int dp[max];
int lis1(int array,int n)
if(dp[i]>max)
max=dp[i];
} return max;
}int minvalue(int array,int n)
int lis2(int array,int n)
} //假設當前最長序列大於最長遞增序列長度,更新最長資訊
if(dp[i]>nmaxlis)
else if(maxv[j]>n;
cout<<"please input array values:"<>array[i];
cout<<"lis1: "《原來寫過一篇二分搜尋的解法,時間複雜度o(n*lgn):最長遞增子串行
最長遞增子串行
這是微軟實習生筆試遇到的,題意 求乙個陣列中最長遞增子串行的長度。要求選擇該題最好演算法的時間複雜度和空間複雜度。答案 時間複雜度o nlgn 空間複雜度o n 這題明顯用動態規劃來解。假設在目標陣列array 的前i個元素中,以array i 元素為最大元素的遞增子串行的長度是lis i 那麼 遞...
最長遞增子串行
最長遞增子串行又叫做最長上公升子串行 子串行,正如lcs一樣,元素不一定要求連續。本節討論實現三種常見方法,主要是練手。題 求乙個一維陣列arr i 中的最長遞增子串行的長度,如在序列1,1,2,3,4,5,6,7中,最長遞增子串行長度為4,可以是1,2,4,6,也可以是 1,2,4,6。方法一 d...
最長遞增子串行
最長遞增子串行 求乙個字串的最長遞增子串行 如 dabdbf最長遞增子串行就是abdf,長度為4 這是一道基本的動態規劃求解的題目,與此類似的還有 最長公共子串行 分析 用一維陣列dp i 來儲存以a i 為末元素的最長遞增子串行的長度,那麼dp i 至少為1 即包含它本身 往前尋找,如果存在a j...