4D:Mysterious Present
题意简述
给出一个限制
>(w,h)
和
n
个物品的二维信息
求物品二维都满足限制的前提下,最长严格上升子序列
xi>xi−1,yi>yi−1
。
数据范围
1≤n≤ 5000
1≤w,h≤106
1≤xi,yi≤106
思路
按照一维排序,第二维就是一个LIS。
注意二分的时候是lower_bound等于的也要包括。
时间复杂度
O(nlogn)
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct data{
int x,y;
int id;
bool operator < (const data &n1) const
{
return x==n1.x ? y>n1.y :x<n1.x;
}
}d[5010];
int n,w,h,t,tail;
int g[5010],pre[5010];
int in()
{
char ch=getchar();
while (ch<'0'||ch>'9')
ch=getchar();
int ret=0;
while (ch>='0'&&ch<='9')
ret=ret*10+ch-'0',ch=getchar();
return ret;
}
bool cmp(const int &a,const int &b)
{
return d[a].y<d[b].y;
}
int dfs(int x)
{
if (pre[x])
dfs(pre[x]);
printf("%d ",x);
}
int main()
{
n=in(),w=in(),h=in();
for (int i=1;i<=n;i++)
d[i].x=in(),d[i].y=in(),d[i].id=i;
sort(d+1,d+n+1);
g[tail++]=0;
for (int i=1;i<=n;i++)
{
if (d[i].x<=w||d[i].y<=h)
continue;
if (d[i].y>d[g[tail-1]].y)
{
g[tail++]=i;
pre[d[i].id]=d[g[tail-2]].id;
}
else
{
t=lower_bound(g,g+tail,i,cmp)-g;
g[t]=i;
pre[d[i].id]=d[g[t-1]].id;
}
}
printf("%d\n",tail-1);
if (tail>1)
dfs(d[g[tail-1]].id);
return 0;
}