題目
對於最長上公升子串行,我們最開始最常用的就是用dp,用兩個for迴圈來暴力計算結果,時間複雜度為n^2,要求串的長度不能超過10^4,而有些有需要我們處理高達10^7次方到10^8次方,用的優化方法是貪心加二分,
我們用dp的時候會存下所有的序列,然而我們需要的只是最長的,那我們就可以處理乙個陣列sum,它記錄的是計算到i時最長串長度為len,len-1,len-2,到1 的串的最後乙個數這樣做的原因就是我們需要求的是最長的串,但每一次能讓串長度增加的都是比最後乙個還要大的,那它之前的資料完全是不需要的 ,我就可以用來記錄 len-1長度時末位數最小的
例如 2 4 6 3 5 1 6
原資料p[0]=2 p[1]=4 p[2]=6 p[3]=3 p[4]=5 p[5]=1 p[6]=6
len =0; sum[len]=p[0] /*初始化*/
sum[len]sum[len]=p[i] : 可以不用處理
sum[len]>p[i] : p[i]的資料比長度為len時的末尾數小, 但是它有可能比長度 小於len某位末尾數字小替換
處理 int s=lower_bound(sum,sum+len,p[i])-sum sum[s]=p[i];
資料模擬 初始化 len=0,sum[len]=p[0]=2;
i 0 1 2 3 4 5 6
p[i] 2 4 6 3 5 1 6
len 0 0->1 1->2 2 2 2 2->3
sum sum[len]=p[i] p[i]>sum[len] p[i]>sum[len] p[i]sum[len]
不處理 len++ len++ len len len len++
sum[len]=p[i] sum[len]=p[i] 第乙個比3大的 第乙個比5大的 第乙個比1大的 sum[len]=p[i]
數是4 sum[1]=3; 數是6 sum[2]=5; 是2 sum[0]=1;
#include using namespace std;
int main()
else if(p[i]}
cout
}
最長上公升子串行nlogn演算法
這題目是經典的dp題目,也可叫作lis longest increasing subsequence 最長上公升子串行 或者 最長不下降子串行。很基礎的題目,有兩種演算法,複雜度分別為o n logn 和o n 2 a.o n 2 演算法分析如下 a 1 a n 存的都是輸入的數 1 對於a n 來...
最長上公升子串行nlogn演算法
定義d k 長度為k的上公升子串行的最末元素,若有多個長度為k的上公升子串行,則記錄最小的那個最末元素。注意d中元素是單調遞增的,下面要用到這個性質。首先len 1,d 1 a 1 然後對a i 若a i d len 那麼len d len a i 否則,我們要從d 1 到d len 1 中找到乙個...
最長上公升子串行nlogn演算法
這題目是經典的dp題目,也可叫作lis longest increasing subsequence 最長上公升子串行 或者 最長不下降子串行。很基礎的題目,有兩種演算法,複雜度分別為o n logn 和o n 2 a.o n 2 演算法分析如下 a 1 a n 存的都是輸入的數 1 對於a n 來...