1. 程式人生 > >51Nod1134 最長遞增子序列(動歸)

51Nod1134 最長遞增子序列(動歸)

這道題用動歸的思想寫,在所給的陣列中找到最長遞增子序列。定義一個新的陣列存最長子序列,第i項如果大於陣列的最後一項,就加入陣列,如果小於,就用二分查詢找到第一個大於第i項的數,然後取代之。

lower_bound( begin,end,num):從陣列的begin位置到end-1位置二分查詢第一個大於或等於num的數字,找到返回該數字的地址,不存在則返回end。通過返回的地址減去起始地址begin,得到找到數字在陣列中的下標。

具體程式碼如下:

#include<iostream>
#include<cstring> 
#include<algorithm>
using namespace std;
int dp[50001];
int main()
{
	int n;
	cin>>n;
	int a[50001],i;
	for(i=0;i<n;i++)
		cin>>a[i];
	dp[0]=a[0];
	int len=0;
	for(i=1;i<n;i++)
	{
		if(a[i]>dp[len])
			dp[++len]=a[i];
		else
		{
			int t=lower_bound(dp,dp+len,a[i])-dp; 
//			dp到dp+len容易寫錯成到dp+len-1
			dp[t]=a[i];
		}	
//		cout<<dp[len]<<endl;	
	}
//	for(i=0;i<=len;i++)
//		cout<<dp[i];
	cout<<len+1<<endl;
	return 0;
 }