bsoj2234 最长上升子序列nlogn算法

20 篇文章 0 订阅
17 篇文章 0 订阅

唉今天是2014年的最后一天,照例把所有时间都用在信息上,没有带任何作业回家,不知道明天要补多少作业。。似乎只有三张卷子而已。。

感觉今天真的很浮躁,我都不知道自己想干什么,看题也看不进去,比赛录像也不想看,想去打台球又觉得确实太过分。。

真纠结啊我擦

今天下午在自习室洋务了半天,看xinyue的dp讲义,学了一下nlogn的lis算法。。。。


废话不说了。。。

f表示长度为i的上升子序列最后一个数最小是多少。显然数组f是单增的。
读到一个新的数x后,找到某个i使得x>f[i]且x<=f[i+1],于是用x去更新f[i+1];特别地,如果所有的f[i]都小于x,则增加f的长度。
最后看f数组有多长就行了。
由于f单增,所以查找i时可以用二分查找,因此时间复杂度为O(nlogn)。


#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>

using namespace std;

int n,a[200000+9],f[200000+9];

int main()
{
	int mid,len=1;
	int t;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	f[1]=a[1];
	for(int i=2;i<=n;i++)
		if(a[i]>f[len])
		{
			len++;
			f[len]=a[i];
		}
		else
		{
			int l=1,r=len;
			while(l<=r)
			{
				mid=(l+r)/2;
				if(f[mid]<a[i])
					l=mid+1;
				else
					r=mid-1;
			}
			f[l]=a[i];
		}
	printf("%d",n-len);
	return 0;
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值