1. 程式人生 > >題目1533:最長上升子序列-九度

題目1533:最長上升子序列-九度

題目描述:

給定一個整型陣列, 求這個陣列的最長嚴格遞增子序列的長度。 譬如序列1 2 2 4 3 的最長嚴格遞增子序列為1,2,4或1,2,3.他們的長度為3。

輸入:

輸入可能包含多個測試案例。
對於每個測試案例,輸入的第一行為一個整數n(1<=n<=100000):代表將要輸入的序列長度
輸入的第二行包括n個整數,代表這個陣列中的數字。整數均在int範圍內。

輸出:

對於每個測試案例,輸出其最長嚴格遞增子序列長度。

樣例輸入:
4
4 2 1 3
5
1 1 1 1 1
樣例輸出:
2
1

推薦指數:※※

dp O(n^2)的思路已經不要在敘述了。

這裡使用seq記錄當最長序列長度為x時序列的最大值可以取到最小值(為後面的數留機會,是取得更大序列的可能性更大),seq[x]記錄的就是相應的值。

這裡題外話,算數運算子的優先順序高於移位運算子,記得加上括號。

#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
using namespace std;
const int N=10001;
int pos_min(vector<int> *num,int val){
   int low=0,high=(*num).size()-1;
   while(low<=high){
       int mid=low+((high-low)>>1);
       if((*num)[mid]>=val)
           high=mid-1;
       else if((*num)[mid]<val)
           low=mid+1;
   }
   return low;
}
int max_seq(int *num,int len){
    int i;
	vector<int> seq;
    for(i=0;i<len;i++){
		int index=pos_min(&seq,num[i]);
		if(index>=seq.size())
			seq.push_back(num[i]);
		else
			seq[index]=num[i];
	}
	return seq.size();
}
int main()
{
	int n,i;
	while(scanf("%d",&n)!=EOF){
		int *num=new int [n];
		for(i=0;i<n;i++)
			scanf("%d",&num[i]);
		int longest=max_seq(num,n);
		printf("%d\n",longest);
	}
	return 0;
}