经典的上升子序列和不上升子序列问题,模板题
lower_bound && upper_bound
lower_bound,查找升序序列中第一个大于等于x的数位置
upper_bound,查找升序序列中第一个大于x的数位置
降序怎么办,用greater()
不上升子序列O(nlogn)
维护一个栈(单调栈)
假如该数可以放到最后面,就直接放到最后面
否则,这个数其实可以扔掉
但为了避免应该选这个数而不选中间的数,给后面更大的容错空间
用这个数替代比他大的第一个数
同时又不会导致栈的大小改变
上升子序列与不上升子序列类似
区别是不需要greater了
代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int h[N], f[N], st[N];
int idx, tmp, top;
int main(){
while(cin>>tmp){
h[idx++] = tmp;
}
st[top++] = h[0];
for(int i = 1;i < idx;i++){
if(st[top - 1] >= h[i]){
st[top++] = h[i];
continue;
}
int j = upper_bound(st, st + top, h[i], greater<int>()) - st;
st[j] = h[i];
}
cout<<top<<endl;
top = 0;
st[top++] = h[0];
for(int i = 1;i < idx;i++){
if(st[top - 1] < h[i]){
st[top++] = h[i];
continue;
}
int j = lower_bound(st, st + top, h[i]) - st;
st[j] = h[i];
}
cout<<top<<endl;
return 0;
}