思路很簡單,維護乙個長度為k時的最長上公升子串行結尾元素是d[k]的陣列,因為前面的元素已經插入了,後面的元素對前面的只有更優的影響,所以只掃一遍原陣列就能求得。
推薦看這篇部落格:講得很詳細
#include using namespace std;
const int n = 1e5+7;
int a[n],d[n],len,n;
int findpos(int x)
return l;
}int main()
printf("%d",len);
return 0;
}
也可以用stl的lower_bound代替二分查詢
#include using namespace std;
const int n = 1e5+7;
int a[n],d[n],len,n;
int main()
printf("%d",len);
return 0;
}
同理,也有最長下降子串行的**:
#include using namespace std;
const int n = 1e5+7;
int a[n],d[n],len,n;
bool cmp(int x,int y)
int main()
printf("%d",len);
return 0;
}
洛谷p1020 飛彈攔截(nlogn做法)
模板的求最長下降子串行和最長上公升子串行,降序即乙個系統最多攔截的數量,公升序因為每公升一次就一定多用乙個系統,所以公升序長度即需要的系統數。
洛谷p1439
求兩個排列的最長公共子串行,需要處理一下兩個陣列,然後實質是求最長上公升子串行,原理見引用。
我們可以以第乙個串為標準,用第二個串來匹配第乙個串,看能匹配多少,所以,其實第乙個串的每個數字其實影響不大,只有知道它對應了第二串的哪個數字就好了,那麼我們為什麼不把他給的串重新定義一下?**:比如他的樣例:3 2 1 4 5 我們把他變成 1 2 3 4 5 用乙個陣列記錄一下每個數字變成了什麼,相當於離散化了一下3-1;2-2;1-3;4-4;5-5;
現在我們的第二串1 2 3 4 5 按我們離散化的表示:3 2 1 4 5
可能有些人已經懂了,我們把第乙個串離散化後的陣列是滿足上公升,反過來,滿足上公升的也就是滿足原串的排列順序的,(如果你不懂的話可以多看幾遍這個例子)o(∩_∩)o~
好了 ,現在的問題就變成了求乙個最長不下降序列!好了!解決完成!
//兩個n的全排列的最長公共子串行,因為是兩個排列,記錄第二個陣列的第bi位數k在第乙個陣列的位置ai
//然後求第二個陣列對應每乙個數在第乙個陣列位置的陣列的最長公共子串行,因為只要順序一致,不相鄰一定也是公共子串行
#include using namespace std;
const int n = 100007;
int a[n], b[n], ans[n], cnt, n;
int main()
for(int tmp, i = 1; i <= n; i++)
cnt = 1, ans[cnt] = b[1];
for(int i = 2; i <= n; i++)
printf("%d",cnt);
return 0;
}
最長上公升子串行 nlogn
最長上公升子串行中對於數ipt i 向前遍歷,當數ipt j 小於ipt i 則ipt j 可作為上公升序列中ipt i 的前乙個數字 dp i max 若現在有兩個狀態a,b 滿足dp a dp b 且 ipt a ipt b 則對於後面的狀態dp a 更優 因為若ipt i dp b 則必然ip...
最長上公升子串行nlog n
nlog n 的方法從很久之前就看了,愣是沒看懂,因為這個條件 現在,我們仔細考慮計算f t 時的情況。假設有兩個元素a x 和a y 滿足 f儲存lis長度 1 x y t 2 a x a y a t 3 f x f y 沒看懂,當a x 其實這只是傳遞乙個思想而已,當兩者的lis都一樣時取最小值...
最長上公升子串行 nlogn
fi 表示i長度的上公升子串行的最小末尾元素值 用貪心的辦法,每次訪問乙個小於當前末尾值的元素,就往前二分地找乙個可以替換的位置 include include include include using namespace std define debug x cerr x x endl cons...