1. 程式人生 > >動態規劃之最長上升子序列

動態規劃之最長上升子序列

 問題描述
最長上升子序列(longest increasing subsequence),也可以叫最長非降序子序列,簡稱LIS,不是太難。即一個數的序列bi,當b1 < b2 < … < bS的時候,我們稱這個序列是上升的。對於給定的一個序列(a1, a2, …, aN),我們可以得到一些上升的子序列(ai1, ai2, …, aiK),這裡1 <= i1 < i2 < … < iK <= N,但必須按照一定。比如,對於序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。這些子序列中最長的長度是4,比如子序列(1, 3, 5, 8)。

 解題思路與演算法思想

如果我們要用動態規劃解這道題的,首要要解決的問題有兩點
	1.如果我們已知前這個序列的前k-1項組成的序列的全部資訊(也就是前k-1位每一位的最
	長上升子序列),如何求第k項的最長上升子序列
	2.如何設定一個邊界條件,使得這個向前遞迴的求法不至於無限迴圈
  • 我們首先來解決第一個問題
第一個要考慮的 :就是將前k-1個元素組成的數集 個的最長上升子序列 進行判斷
		判斷什麼呢?判斷第k個元素是否能夠一最後一項的身份成為新的最長子序列的一員
			這樣就有涉及到一個問題:
			我們需要一組二額外的整形去記錄前k-1個元素的最長上升子序列的最大元素是多少
				如果>=第k個元素
					那麼第k個元素無法加入
				否則
					可以加入				
  • 第二個問題也很好解決
	顯然,如果進行到前1個元素的時候
 - 	這個元素的最長上升子序列毫無疑問的是1

 程式模型的建立
通過遞迴的方式以此計算前x個的最長上升子序列並且一路爬升到n

 資料結構的選用

  • 陣列

 程式設計流程

  • 輸入資料
  • 遞迴判斷
  • 輸出結果

 程式設計偽碼演算法

	for(int i = 0 ;i<n ;i++)
		{
			if(a[i]<a[n])
			{
			
				tem =  we_find(i)+1 ;
				
			}
			else
			{
				swap(a[i],a[n]) ;
				
				tem =  we_find(i) ;
			
				swap(a[i],a[n]) ;
			}
			if(tem>sum)
			{
				sum = tem ;
			}
		}

 源程式編碼清單

#include<iostream>
#include<vector>
#include<string> 
#include<algorithm>
using namespace std ;
vector<int>a ;
vector<int>mark ;

int we_find(int n) ;
int main(void)
{
	
	int n ;
	scanf("%d",&n) ;
	
	
	for(int i = 0 ;i<n ;i++)
	{
		mark.push_back(-1) ;
	}
	
	int tem ;
	for(int i = 0 ; i<n ;i++)
	{
		scanf("%d",&tem) ;
		a.push_back(tem) ;
	}
	for(int i = 0 ;i<n ;i++)
	{
		printf("%d\n",we_find(i)) ;
	}
	//printf("%d",we_find(a.size()-1)) ;
	
}
int we_find(int n)
{
	int sum  = 0 ;
	int tem ;
	if(n==0)
	{
		return 1 ;
	}
	//if(mark[n]!=-1)
	//{
	//	return mark[n] ;
	//}
	else
	{
		for(int i = 0 ;i<n ;i++)
		{
			if(a[i]<a[n])
			{
			
				tem =  we_find(i)+1 ;
				
			}
			else
			{
				swap(a[i],a[n]) ;
				
				tem =  we_find(i) ;
			
				swap(a[i],a[n]) ;
			}
			if(tem>sum)
			{
				sum = tem ;
			}
		}
		//mark[n] = sum ;
		return sum ;
		
	}
}

 程式輸入、輸出

輸入:
7
1 7 3 5 9 4 8 
輸出:
4

輸入輸出檔案,或程式執行結果截圖
在這裡插入圖片描述
 時間與空間複雜度分析
時間複雜度:n^2
 程式使用說明

 總結與完善