最长子序列LIS

最长子序列LIS

(1).暴力dp
//LIS 基础dp法
//思路:1.dp[i]储存的是以i结尾的最长上升子序列长度
//2.跟前边的aj比较, 如果a[i]>a[j],就a[i]可以加到j序列后边,
//所以dp[i]=dp[j]+1 ,多次取max即可
//ps 如果都不可以加,则dp[i] = 1 ;可以理解为创造新序列
//3.ans多次取max 即:ans=max(ans,dp[i])

#include<iostream>
#include<cstdio>
using namespace std ;
const int maxn = 3e4+100 ;
int dp[maxn] , a[maxn] ;
int main()
{
	int t ;
	while(~scanf("%d",&t))
	{
		for(int i = 1 ; i <= t ; i++) 
		{
			scanf("%d",&a[i]) ;
			dp[i] = 1 ;
		}
		int ans = dp[1] ;
		for(int i = 1 ; i <= t ; i++)
		{
			for(int j = 1 ; j < i ; j++)
			{
				if(a[j] < a[i]) dp[i] = max(dp[i],dp[j]+1) ;
			}
			ans = max(ans,dp[i]) ;
		}
		printf("%d\n",ans) ;
	}
	return 0 ;
}

二分
//二分思路:
//1.a[i]>d[len]即a[i]大于当前最长子序列的最后一个元素,就加在序列之后:d[++len]=a[i]
//2.否则 lower_bound 找到大于等于的元素,替代掉
//即 j = lower_bound(d+1,d+1+len,a[i])-d
//d[j] = a[i]
//ps.因为d[0]=0,所以-d ;如果-(d+1),则会插在前一位 如:5-0=5;5-1=4
//3.ps如果小于的话,就插在第一位,即替换掉第一个数
//所以初始化序列d[0]=0 ;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std ;
const int maxn = 3e4+5 ; 
int d[maxn], a[maxn] ;//d储存该序列,len储存长度 
int main()
{
	int t ;
	while(~scanf("%d",&t))
	{
		memset(a,0,sizeof(a)) ;
		for(int i = 1 ; i <= t ; i++) scanf("%d",&a[i]) ;
		int len = 0 ;
		d[0] = 0 ; 
		for(int i = 1 ; i <= t ; i++)
		{
			if(a[i] > d[len]) 
			{
				d[++len] = a[i] ;
				//printf("d[%d]=%d\n",len,d[len]) ;
			}
	    	else
	    	{
		    	int j = lower_bound(d+1,d+len+1,a[i])-d ;
		    	d[j] = a[i] ;
		    	//printf("d[%d]=%d\n",j,d[j]) ;
		    }
		}
		printf("%d\n",len) ;
	}
	return 0 ;
}

二者比较
//比较dp与二分:
//dp双层循环 ,复杂度为n*n
//二分 nlogn 少了第二层循环
//因为LIS只需要最长的长度,不需要具体的序列
//所以二分思维巧妙,用的是设置门槛的思路,即不停的让小的替代大的,把门槛降低,
//以达到最后一个数,即真正的序列门槛降低,这样就可以尽可能地增加长度,让更多元素进入序列
//ps 二分中的d[]不是实际上的元素排列,但是它所起到的降低真正门槛的作用,没有问题
//因为他只会降低之后的门槛,也就是说,不会减小当前子序列的长度

例题
dp专题 I - 最少拦截系统 HDU - 1257
挖坑
还没学树状数组维护LIS

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值