轉載請註明出處:優YoU
http://user.qzone.qq.com/289065406/blog/1300023619
提示:
動態規劃,求LIS最大不下降子序列
O(n^2)和O(n*logn)演算法都能完美AC
不懂的就去看看LIS的概念就會做了
我把兩種演算法都貼出來:
//Memory Time //228K 16MS //O(n^2)演算法#include<iostream>using namespace std;int main(int i,int j){int n;while(cin>>n){int* sq=new int[n];int* dp=new int[n]; //dp[i]表示以第i個位置為終點的最長不下降序列的長度for(i=0;i<n;i++)cin>>sq[i];int max_length=0;for(i=0;i<n;i++){dp[i]=1; //初始化dp[0]=1,其他最小值為1for(j=0;j<i;j++)if(sq[j]<sq[i] && dp[i]<dp[j]+1)dp[i]=dp[j]+1;if(max_length<dp[i])max_length=dp[i];}cout<<max_length<<endl;delete sq,dp;}return 0;}
===========華麗的分割線=============
//Memory Time //224K 0MS //O(n*logn)演算法#include<iostream>using namespace std;const int inf=10001;int binary_search(int ord[],int digit,int length) //二分法搜尋digit,若str中存在digit,返回其下標{ //若不存在,返回str中比digit小的最大那個數的(下標+1)int left=0,right=length;int mid;while(right!=left){mid=(left+right)/2;if(digit==ord[mid])return mid;else if(digit<ord[mid])right=mid;elseleft=mid+1;}return left;}int main(int i,int j){int n;while(cin>>n){int* sq=new int[n+1];int* ord=new int[n+1]; //對於dp[]的每一個取值k,ord[k]記錄滿足dp[i]=k的所有sq[i]中的最小值,即ord[k]=min{sq[i]} (dp[i]=k)for(i=1;i<=n;i++)cin>>sq[i];int max_length=0;ord[0]=-1; //下界無窮小int len=1; //ord的長度for(i=1;i<=n;i++){ord[len]=inf; //上界無窮大,指標len總是指向ord最後一個元素的後一位j=binary_search(ord,sq[i],len);if(j==len) //sq[i]大於ord最大(最後)的元素len++;ord[j]=sq[i];}cout<<len-1<<endl; //len要減去ord[0]的長度1delete sq,ord;}return 0;}