給出乙個序列,求非下降序列最大長度,或非上公升序列最大長度
首先看一下時間複雜度為o(n*n)的一維遞推演算法
這裡給出乙個序列,
第一行為原序列,第二行,代表第乙個數字到此為止最大遞增序列長度
我們來解釋一下第二行數字t怎麼推的:
t1:本身數字長度就是1,如果只有乙個字元那麼最大長度就是1
t2:由於2>1,所以取k1狀態的解再加上本身長度1,然後取最大值,k1前面沒數了,所以繼續往後走
t3:4>2,繼續取k2狀態的解加1在比較取最大值得3,此時還要再比較k1值,同理4>1,取k1狀態的解加1和之前比較好的3取最大值,得3還是最大的,所以k4這個狀態最大遞增序列為3..
.到了k6,也就是到第六個數時,3<7,繼續向前比較知道3>2,取t2加1比較再取最大值。
.就這樣每一輪都要和前面所有數比較才能得出最終結果;
**如下:時間複雜度o(n*n)
intdp(
int a,
int n)
} max_long =
max(max_long, long_dp[i]);
}return max_long;
}
我們再來看看時間複雜度為o(nlogn)這個演算法首先需要建立陣列b,這個陣列是用來幹嘛的呢?就是用來儲存最長的遞增序列的。
上面圖代表我們如何乙個乙個插入陣列b,首先插入第乙個數,因為本身就是乙個長度為1的序列,再插入2,2>1,直接將他插入末尾,同理一直到7,此時陣列為1,2,4,6,7,說明截至7這個位置,最大長度為5,且最大長度序列為:1,2,4,6,7
當再次插入7後邊的3時,3<7,那麼這個時候怎麼辦?我們尋找3以前的比自己大的最小的數也就是4這個數,在進行替換,我們為什麼替換呢?
因為截至7為止最大長度為5,我們將4替換以後並不影響之前每個數字之下的最大長度,而且也得到了3這個數字對應的最大長度為3,序列為1,2,3。這樣做的目的是為了,不能排除整個數字串最終結果裡面不會包含這個3,乙個小的數在前邊,當然比乙個大的數在前邊更有可能找出最長序列
同理4,5替換6,7
6,9再加入5的後邊,此時的b陣列長度就是最大序列長度
int
lnds
(int n,
int a)
else
}return val;
}
**中函式:
本題中b陣列本身就是乙個非遞減陣列 upper_bound()以及lower_bound()函式前提條件為傳入i到j位址中的數為非遞減,也就是傳入區間必須為排序好的
**中函式:
upper_bound(i,j,key)表示從 i 位址到 j(不包括j) 位址查詢第乙個比自己大的數,返回這個數的位址
如果這個題目求的是非下降最大序列,我們就要考慮想等情況
這個時候函式需要改變為lower_bound
lower_bound(i,j,key)表示從 i 位址到 j(不包括j) 位址查詢第乙個比自己大或者等於的數,返回這個數的位址
此**時間複雜度為o(nlogn)
最長上公升子串行O NlogN 演算法
給出乙個長度為n的序列,請求出其最長上公升子串行的長度。首先很容易想到o n2 的演算法 f i 表示1 i最長上公升子串行長度則 f i m ax 1 1 j a j i 顯然我們需要的只是滿足 1 j a j i 這一條件的最大f j 那麼我們為何不將他記錄下來呢 用g i 表示f j i 時的...
LIS最長上公升子串行O(nlogn 演算法
正常的求lis的方法是用dp來做,時間複雜度為o n 2 但是面對一些題目的時候這個複雜度就有點高了,就去學了一下nlogn的解法。主要運用到了二分查詢,stl裡面的lower bound 也可以。upper bound i 返回的是鍵值為i的元素可以插入的最後乙個位置 上界 lower bound...
最長上公升子串行 O nlogn
題目描述 input 輸入乙個整數n 表示接下來有 n 個數輸入。output 輸出當前數列最長上公升子串行的長度。直接上 最長下降子串行 最長山峰序列都可以以該問題為母問題 進行延伸。include include using namespace std define max 1000 int s...