D e s c r i p t i o n Description Description
带求路径二维导弹拦截
数据范围: n ≤ 5000 n\leq 5000 n≤5000
S o l u t i o n Solution Solution
和洛谷的球赛的解法一样,排序后强行 d p dp dp,复杂度: O ( n 2 ) O(n^2) O(n2)
本人码的 O ( n l o g n ) O(nlogn) O(nlogn)方法不知为啥一直过不了,如果发现问题的大爷麻烦在下面评论,谢谢!
n 2 C o d e n^2\ \ Code n2 Code
#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;int f[5001],pre[5001],n,W,H,minw,minh,m,Ans;
struct node{int w,h,id;}p[5001];
inline bool cmp(node x,node y){return x.w<y.w||x.w==y.w&&x.h<y.h;}
inline int read()
{
char c;int d=1,f=0;
while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
inline void print(int x)
{
if(!x) return;
print(pre[x]);
printf("%d ",p[x].id);
}
signed main()
{
n=read();minw=read();minh=read();
for(register int i=1;i<=n;i++)
{
W=read();H=read();
if(W>minw&&H>minh) p[++m]=(node){W,H,i};
}
sort(p+1,p+1+m,cmp);
for(register int i=1;i<=m;i++)
{
f[i]=1;
for(register int j=1;j<i;j++)
if(p[i].w>p[j].w&&p[i].h>p[j].h&&f[j]>=f[i])
f[i]=f[j]+1,pre[i]=j;
if(f[i]>f[Ans]) Ans=i;
}
if(!Ans) return puts("0")&0;
printf("%d\n",f[Ans]);
print(Ans);
}
O ( n l o g n ) C o d e O(nlogn)\ \ Code O(nlogn) Code
#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;int pre[5001],n,W,H,minw,minh,m,Ans;
bool flag[5001];
struct node{int w,h,id;}p[5001],f[5001];
inline bool operator <(node x,node y){return x.h<y.h&&x.w<y.w;}
inline bool cmp(node x,node y){return x.w<y.w||x.w==y.w&&x.h<y.h;}
inline int read()
{
char c;int d=1,f=0;
while(c=getchar(),!isdigit(c)) if(c=='-') d=-1;f=(f<<3)+(f<<1)+c-48;
while(c=getchar(),isdigit(c)) f=(f<<3)+(f<<1)+c-48;
return d*f;
}
signed main()
{
n=read();minw=read();minh=read();
for(register int i=1;i<=n;i++)
{
W=read();H=read();
if(W>minw&&H>minh) p[++m]=(node){W,H,i};
}
sort(p+1,p+1+m,cmp);
for(register int i=1;i<m;i++) if(p[i].w==p[i+1].w) flag[i+1]=true;
for(register int i=1;i<=m;i++)
{
if(flag[i]) continue;
if(f[Ans]<p[i]) f[++Ans]=p[i];
else *lower_bound(&f[1].h,&f[Ans].h,p[i].h)=p[i].h;
}
printf("%d\n",Ans);
for(register int i=1;i<=Ans;i++) printf("%d ",f[i].id);
}