最長上升子序列 LIS

最長上升子序列有好幾種解法,這裏介紹其中比較常用的兩種。

第一種是普通的動態規劃,時間複雜度爲O(N^2),所以寫一些數據比較大的題目就會超時,比如請看這題,沒什麼好說的,直接上代碼。

#include
using namespace std;
int a[10],d[10],n;
int LIS(int *a,int n)
{
	int maxs=1,i,j;
	for(i=2;i<=n;i++)
	{
		for(j=1;ja[j]&&d[j]>m)	//如果下一個元素大於上一個元素,則d[i]=max(d[j]+1,d[i]) 
				d[i]=d[j]+1;
		}
		if(d[i]>maxs)	//d[i]中存儲的是1-i中最長遞增序列 
			maxs=d[i]; 
	}
	return maxs;
}
int main()
{
	cin>>n;
	for(int i(1);i<=n;i++)
		cin>>a[i];
	int len=LIS(a,n);
	cout<

第二種是動態規劃加二分查找,我們知道二分查找適用於大量查找而不適用於移動數據,這種方法正是用元素替換(即新來的滿足條件的元素替換當前的元素)的技巧,巧妙利用了二分查找的這一特點,在普通動態規劃的基礎上利用二分查找將時間複雜度降低爲O(N*logN),註釋寫在代碼中。
#include
#define MAXN 1000
using namespace std;
int a[MAXN],d[MAXN],n; 
int Binsearch(int key,int *d,int l,int r)	//二分查找函數 
{
	while(l<=r)
	{
		int mid=(l+r)>>1;	//利用了位運算,相當於mid=(l+r)/2 
		if(key>d[mid] && keyd[mid])
			r=mid+1;
		else
			l=mid-1;
	}
}
int LIS(int *a,int n)
{
	int len=1,i,j;
	d[1]=a[1];
	for(i=2;i<=n;i++)
	{
		if(a[i]>d[len])	//如果a[i]>d[len],直接將a[i]加到數組d的後面,同時len++; 
		{
			len++;
			d[len]=a[i];
		}
		else	//如果a[i]>n;
	for(int i(1);i<=n;i++)
		cin>>a[i];
	int len=LIS(a,n);
	cout<


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