POJ2533-Longest Ordered Subsequence

全解题报告索引目录 -> 【北大ACM – POJ试题分类

转载请注明出处:http://exp-blog.com

-------------------------------------------------------------------------

 

 

提示:

动态规划,求LIS最大不下降子序列

 

O(n^2)和O(n*logn)算法都能完美AC

 

不懂的就去看看LIS的概念就会做了

 

 

我把两种算法都贴出来:

 

 

//Memory Time 
//228K   16MS 

//O(n^2)算法
#include<iostream>
using namespace std;

int main(int i,int j)
{
	int n;
	while(cin>>n)
	{
		int* sq=new int[n];
		int* dp=new int[n];  //dp[i]表示以第i个位置为终点的最长不下降序列的长度

		for(i=0;i<n;i++)
			cin>>sq[i];

		int max_length=0;
		for(i=0;i<n;i++)
		{
			dp[i]=1;  //初始化dp[0]=1,其他最小值为1
			for(j=0;j<i;j++)
				if(sq[j]<sq[i] && dp[i]<dp[j]+1)
					dp[i]=dp[j]+1;

			if(max_length<dp[i])
				max_length=dp[i];
		}
		cout<<max_length<<endl;

		delete sq,dp;
	}
	return 0;
}

 

 

===========华丽的分割线=============

 

 

//Memory Time 
//224K   0MS 

//O(n*logn)算法
#include<iostream>
using namespace std;
const int inf=10001;

int binary_search(int ord[],int digit,int length)   //二分法搜索digit,若str中存在digit,返回其下标
{                                                   //若不存在,返回str中比digit小的最大那个数的(下标+1)
	int left=0,right=length;
	int mid;
	while(right!=left)
	{
		mid=(left+right)/2;
		if(digit==ord[mid])
			return mid;
		else if(digit<ord[mid])
			right=mid;
		else
			left=mid+1;
	}
	return left;
}

int main(int i,int j)
{
	int n;
	while(cin>>n)
	{
		int* sq=new int[n+1];
		int* ord=new int[n+1];  //对于dp[]的每一个取值k,ord[k]记录满足dp[i]=k的所有sq[i]中的最小值,即ord[k]=min{sq[i]} (dp[i]=k)

		for(i=1;i<=n;i++)
			cin>>sq[i];

		int max_length=0;
		ord[0]=-1;  //下界无穷小
		int len=1;  //ord的长度
		for(i=1;i<=n;i++)
		{
			ord[len]=inf;  //上界无穷大,指针len总是指向ord最后一个元素的后一位
			j=binary_search(ord,sq[i],len);
			if(j==len)  //sq[i]大于ord最大(最后)的元素
				len++;
			ord[j]=sq[i];
		}
		cout<<len-1<<endl; //len要减去ord[0]的长度1

		delete sq,ord;
	}
	return 0;
}


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值