單調遞增最長子序列(LIS)【NY】-17

點擊打開鏈接

單調遞增最長子序列

時間限制:3000 ms  |  內存限制:65535 KB
難度:4
描述
求一個字符串的最長遞增子序列的長度
如:dabdbf最長遞增子序列就是abdf,長度爲4
輸入
第一行一個整數0<n<20,表示有n個字符串要處理
隨後的n行,每行有一個字符串,該字符串的長度不會超過10000
輸出
輸出字符串的最長遞增子序列的長度
樣例輸入
3
aaa
ababc
abklmncdefg
樣例輸出
1
3
7
來源
經典題目

解析:LIS的裸題,

代碼:

1.O(  n^2  )

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define INF 0x7fffffff
const int maxn=10005;
int dp[maxn];
char a[maxn];
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%s",a);
		int l1=strlen(a);
		int ans=0;
		for(int i=0;i<l1;i++)
		{
			dp[i]=1;           //只包含ai的子序列
			for(int j=0;j<i;j++)
			{
				if(a[j]<a[i])        //在滿足j<i並且aj<ai的以aj爲結尾的上升子列末尾,追加上ai後得到的子序列
				dp[i]=max(dp[i],dp[j]+1);
			}
			ans=max(ans,dp[i]);
		}
		printf("%d\n",ans);
	}
	return 0;
} 


2.

O(  nlogn  )

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define INF 0x7fffffff
const int maxn=10005;
int dp[maxn];
char a[maxn];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
    	scanf("%s",a);
    	int l1=strlen(a);
    	fill(dp,dp+l1,INF);
    	for(int i=0;i<l1;i++)
    	*lower_bound(dp,dp+l1,a[i])=a[i];
    	printf("%d\n",lower_bound(dp,dp+l1,INF)-dp);
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章