最初没有看出列末数字的有序性,做了模拟,超时21分
正确做法是二分
模拟代码:
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
int n;
queue<int> q[N];
int cnt;//到第几个队列
int t;//空出来几个队列
map<int,int> tail;//队列末尾数
map<int,int> head;//队头数对应队列
int now;//该出哪个数了
int res;
int main()
{
cin>>n;now=n;
while(n--)
{
int x;cin>>x;
if(now==x)
{
cnt++;
res=max(res,cnt-t);
t++;
res=max(res,cnt-t);
now--;
while(head[now])
{
int pos=head[now];
q[pos].pop();
head[now]=0;
if(q[pos].empty())
{
t++;
tail[pos]=0;
}
else
{
head[q[pos].front()]=pos;
}
now--;
res=max(res,cnt-t);
}
continue;
}
bool f=false;
for(int i=1;i<=cnt;i++)
{
if(tail[i]&&tail[i]>x)
{
tail[i]=x;
q[i].push(x);
f=true;
break;
}
}
if(!f)
{
cnt++;
q[cnt].push(x);
head[x]=cnt;
tail[cnt]=x;
}
res=max(res,cnt-t);
}
cout<<res;
// cout<<cnt<<" "<<t;
}
二分代码:
#include<bits/stdc++.h>
using namespace std;
int n;
int s[100005];
int t=0;
int main()
{
cin>>n;
while(n--)
{
int x;cin>>x;
int l=1,r=t;
while(l<r)
{
int mid=l+r>>1;
if(s[mid]>x) r=mid;
else l=mid+1;
}
if(s[l]>x) s[l]=x;
else s[++t]=x;
}
cout<<t<<endl;
}