题目链接:https://ac.nowcoder.com/acm/contest/3007/C题解做法:
Dilworth定理:一个序列中,连续上升子序列的最小数目(组数)=最长不下降序列的长度,反之也成立。
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct node
{
int x;
int y;
int pos;
}a[100010];
int len;
int n;
int maxdec[100010];
int range[100010];
bool cmp(node a,node b)
{
return a.x<b.x;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].x,&a[i].y);
a[i].pos=i;
}
sort(a+1,a+n+1,cmp);
//最长下降子序列求法
//len为最大长度,也就是最少的组数
//maxdec数组保存这个最长的序列
//因为本题的特殊性,range数组保存每个元素属于哪一个分组中
for(int i=1;i<=n;i++)
{
int le=1;
int r=len;
while(le<=r)
{
int mid=(le+r)/2;
if(maxdec[mid]<a[i].y)
r=mid-1;
else
le=mid+1;
}
//le指向第一个大于等于a[i].y的位置
maxdec[le]=a[i].y;
if(le>len) len=le;
range[a[i].pos]=le;
}
cout<<len<<endl;
for(int i=1;i<=n;i++)
cout<<range[i]<<" ";
cout<<endl;
return 0;
}