version 3
LIS
O
(
n
l
o
g
n
)
O(nlogn)
O(nlogn)
#include <iostream>
#include <algorithm>
#include <string>
#include <deque>
#include <cstring>
#include <set>
using namespace std;
const int N = 1e4+7;
const int INF = 0x3f3f3f3f;
int q[N];
int low[N];
int main(){
int n, x;
scanf("%d", &n);
fill(low, low+n, INF);
for(int i = 0; i <n; i++){
scanf("%d", q+i);
*lower_bound(low, low+n, q[i]) = q[i];
}
cout<<lower_bound(low, low+n, INF) - low<<endl;
return 0;
}
version 2
1 2 4 8
3 5
6 9
7
始终维护最前面这一列的最小值 如果当前值x能够跟在最接近大于x的后面,则替换
否则 新增一行
#include <iostream>
#include <algorithm>
#include <string>
#include <deque>
#include <cstring>
#include <set>
using namespace std;
int main(){
int n, x;
scanf("%d", &n);
set<int> st; //数据唯一,没有相同值得数据 用lower_bound和upper_boundd结果一样
for(int i = 0; i <n; i++){
scanf("%d", &x);
auto it = st.lower_bound(x);
if(it == st.end()) st.insert(x); //无法替换时,就新增一行
else{
st.erase(it); //先擦除 再插入
st.insert(x);
}
}
cout<<st.size()<<endl; //最后统计有多少行 行只会增加 不会缩小
return 0;
}
version 1
18/25
两个测试点超时
我是直接模拟的
虽然看了很多大佬的代码很简洁,但是我真的理解不了。
心态炸裂
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <cstring>
#include <cstdio>
using namespace std;
const int N = 1e4+7;
deque<int> q[N];
int main(){
int n, x;
cin>>n;
vector<int> nums, sorted;
for(int i = 0; i <n; i++){
cin>>x;
nums.push_back(x);
}
int k = 0, res = 0;
sorted = nums;
sort(sorted.begin(), sorted.end());
for(int i = 0 ; i < n; i++){
//贪心法放入数
for(int j = 0; j < n; j++){
if(q[j].empty() || q[j].front() > nums[i]){ //找一个为空或者末尾小于当前的栈放入该数
q[j].push_front(nums[i]);
res = max(res, j);
break;
}
}
//比对弹出
while(true){
int x = sorted.size();
for(int v = 0; v <= res; v++){
while(q[v].size() > 0 && q[v].back() == sorted.back()) {
q[k].pop_back(); //该栈末尾弹出
sorted.pop_back(); //排序好的末尾也弹出
}
}
if(x == sorted.size()) break; //循环一遍后发现都不合适
if(x == 0){
cout<<res+1<<endl;
return 0;
}
}
}
cout<<res+1<<endl;
return 0;
}