lis指乙個序列中最長的單調遞增(嚴格)的子串行。有一種較為樸素的o(n^2)的做法,我們不多做贅述,我們講一種用單帶棧和二分來實現的o(logn)的演算法
我們從1-n列舉,若該數比棧頂元素大,那麼我們就將該數壓入棧中。否則我們就在整個棧中二分到乙個第乙個大於等於它的數,將其用a[i]替換。
考慮為什麼這樣可行,顯然若我們二分到的數不是棧頂元素,就不會對答案產生影響。只有我們改變了棧頂元素,那麼相當於此時棧中的元素才構成乙個單增的子串行。二分改變非棧頂值,只是為了防止我們將未來可能產生的最優解漏掉
n=read();for(int i=1;i<=n;i++) a[i]=read();
for(int i=1;i<=n;i++)
printf(
"%d\n
",top);
總體**如下:
#include #include#include
#include
#include
#include
#include
using
namespace
std;
inline
intread()
const
int n=100100
;int
n,a[n],stk[n],top;
intmain()
printf(
"%d\n
",top);
return0;
}
動態規劃 LIS
最長遞增子串行 lis 的問題是要找到乙個給定序列的最長子序列的長度,使得子串行中的所有元素被排序的順序增加。例如,lis的長度是6和 lis為。最優子結構 對於長度為n的陣列a n 假設假設我們想求以aj結尾的最大遞增子串行長度,設為l j 那麼l j max l i 1,where i j a ...
動態規劃 LIS
動態規劃是比較重要的演算法啦,打算慢慢寫幾篇部落格總結一下。動態規劃的基本思想是 要求原問題的解,先求出更小一些的問題的解,由子問題的解通過某種方式得到原問題的解。以上是有關動態規劃的一些基本概念和概括。第一篇就先講一下最長遞增子串行 lis 的問題的解決。給出乙個數列a,求a的乙個 長度最大的子數...
動態規劃 LIS問題
最長上公升子串行 longest increasing subsquence 即lis問題是動態規劃解決的乙個經典問題。例如輸入序列1 5 2 3 4 輸出最長上公升子串行的長度 4 子串行為1 2 3 4 動態規劃思路 dp i 為最長子序列最後乙個元素為元序列第i個元素是的最大長度,只要把前面比...