CF4D Mysterious Present

27 篇文章 3 订阅
D e s c r i p t i o n Description Description

带求路径二维导弹拦截

数据范围: n ≤ 5000 n\leq 5000 n5000


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);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值