最长单调递减子序列

本文介绍了两种方法求解最长单调递减子序列问题。第一种是常规动态规划算法,时间复杂度为O(n^2)。第二种方法引入了二分搜索,将时间复杂度降低到O(nlogn)。在动态规划过程中,通过比较当前元素与已知最长子序列的结尾元素,更新最长子序列的长度和结尾元素。
摘要由CSDN通过智能技术生成

方法一:普通动态规划算法,时间复杂度O(n2)。

int LIS(int a[], int n)
{
	int i, j, k;
	int maxlen;
	int *b=new int[n];
	for(i=0, b[0]=1; i<n; i++)
	{
		for(j=0, k=0; j<i; j++)
		{
			if(a[j]>a[i] && k<b[j])
				k=b[j];
			b[i]=k+1;
		}
	}
	
	maxlen=0;
	for(i=0; i<n; i++)
		if(b[i]>maxlen)
			maxlen=b[i];

	return maxlen;
}
int main()
{
	int a[]={9,4,3,2,5,4,3,2};
	cout<<LIS(a, 8)<<endl;
	
}

 

方法二:采用二分搜索算法,时间复杂度O(nlgn)。

 0<=i<n,k是序列a[0:i]的最长单调递减子序列的长度。b[k]是序列a[0:i]中所有长度为k的递减子序列中的最大结尾元素值。

在由i-1到i的循环中,如果a[i]<b[k],则k++,b[k]=a[i];否则k值不变,但要更新b数组。怎么更新b数组呢?如果a[i]>b[1],则b[1]=a[i];若a[i]<b[1],注意到数组b是递减的,则二分搜索找到b[j-1]>a[i]>b[j],更新b[j]=a[i]。

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值