對於這個問題,最直觀的dp方法是cnt[i]表示以height[i]結束的最長遞增子串行的元素的個數,遞迴方程是cnt[i]=max
for(max=i=0;i求出整個數列的最長遞增子串行的長度
if(b[i]>max)
max=b[i];
cout< }
return 0; }
顯然,這種方法的時間複雜度仍為o(n^2);
3、對第二種思路的改進:
第二種思路在狀態轉移時的複雜度為o(n),即在找a[k]前面滿足a[j]#include
using namespace std;
int find(int *a,int len,int n)//若返回值為x,則a[x]>=n>a[x-1]
return left;}
void fill(int *a,int n)
int main()
for(max=i=0;i
if(b[i]>max)
max=b[i];
cout< }
return 0; }
對於這段程式,我們可以用演算法導論上的loop invariants來幫助理解.
loop invariant: 1、每次迴圈結束後c都是單調遞增的。(這一性質決定了可以用二分查詢)
2、每次迴圈後,c[i]總是儲存長度為i的遞增子串行的最末的元素,若長度為i的遞增子序
列有多個,剛儲存末尾元素最小的那個.(這一性質決定是第3條性質成立的前提)
3、每次迴圈完後,b[i]總是儲存以a[i]結尾的最長遞增子串行。
initialization: 1、進入迴圈之前,c[0]=-1,c[1]=a[0],c的其他元素均為1000,c是單調遞增的;
2、進入迴圈之前,c[1]=a[0],儲存了長度為1時的遞增序列的最末的元素,且此時長度為1
的遞增了序列只有乙個,c[1]也是最小的;
3、進入迴圈之前,b[0]=1,此時以a[0]結尾的最長遞增子串行的長度為1.
maintenance: 1、若在第n次迴圈之前c是單調遞增的,則第n次迴圈時,c的值只在第6行發生變化,而由
c進入迴圈前單調遞增及find函式的性質可知(見find的注釋),
此時c[j+1]>c[j]>=a[i]>c[j-1],所以把c[j]的值更新為a[i]後,c[j+1]>c[j]>c[j-1]的性質仍然成
立,即c仍然是單調遞增的;
2、迴圈中,c的值只在第6行發生變化,由c[j]>=a[i]可知,c[j]更新為a[i]後,c[j]的值只會變
小不會變大,因為進入迴圈前c[j]的值是最小的,則迴圈中把c[j]更新為更小的a[i],當
然此時c[j]的值仍是最小的;
3、迴圈中,b[i]的值在第7行發生了變化,因為有loop invariant的性質2,find函式返回值
為j有:c[j-1]長度,即為j-1,把a[i]接在c[j-1]後可得到以a[i]結尾的最長遞增子串行,長度為(j-1)+1=j;
termination: 迴圈完後,i=n-1,b[0],b[1],...,b[n-1]的值均已求出,即以a[0],a[1],...,a[n-1]結尾的最長遞
增子序列的長度均已求出,再通過第8行的迴圈,即求出了整個陣列的最長遞增子串行。
仔細分析上面的**可以發現,每次迴圈結束後,假設已經求出c[1],c[2],c[3],...,c[len]的值,則此時最長遞增子串行的長度為len,因此可以把上面的**更加簡化,即可以不需要陣列b來輔助儲存,第8行的迴圈也可以省略。
#include
using namespace std;
int find(int *a,int len,int n)//修改後的二分查詢,若返回值為x,則a[x]>=n
return left; }
int main()
cout< }
return 0; }
最長遞增子串行 LIS
給定乙個長度為n的陣列,找出乙個最長的單調自增子序列 不一定連續,但是順序不能亂 例如 給定乙個長度為6的陣列a,則其最長的單調遞增子串行為,長度為4.這個問題可以轉換為最長公共子串行問題。如例子中的陣列a,則我們排序該陣列得到陣列a 然後找出陣列a和a 的最長公共子串行即可。顯然這裡最長公共子串行...
最長遞增子串行(LIS)
300.longest increasing subsequence good 給定乙個長度為n的陣列,找出乙個最長的單調遞增子串行 不一定連續,當時先後順序不能亂 更正式的定義是 設l 是n個不同的實數的序列,l的遞增子串行是這樣乙個子串行lin 其中k1。比如陣列a 為,那麼最長遞增子串行為。以...
LIS 最長遞增子串行
最長遞增子串行可以用動態規劃的方法,時間複雜度是o n n 也可以用二分查詢的方法,時間複雜度是o nlogn 首先看二分查詢的方法 思路是,順序插入資料,當插入的資料大於以往的任何值時,插入到最後,若插入的資料不是大於以往的任何值時,首先找到大於要插入資料的乙個值,然後,將要插入的資料將該值替換掉...