最长不下降子序列的两种解法

第一种:O(n^2)的复杂度的解法.

//这里dp数组记录的是到第i个位置,当前最长的子序列的长度
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
int dp[105];
int a[105];
int main()
{
    int n;
    cin>>n;
    int i,j;
    for(i=0;i<n;i++)
    {
        cin>>a[i];
    }
    for(i=0;i<n;i++)
    {
        dp[i]=1;//对每个新的位置,初始化最长长度为1
        for(j=0;j<i;j++)//对于i之前的每个元素和a[i]进行比较,不断更新长度值
        {
            if(a[j]<=a[i])
                dp[i]=max(dp[i],dp[j]+1);
        }
    }
    int ans=0;
    for(i=0;i<n;i++)
    {
        ans=max(ans,dp[i]);
    }
    cout<<ans<<endl;
}

第二种:O(nlogn)的复杂度的解法

//dp记录的是最长子序列中的元素,并且可以输出最长子序列中的元素
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
int a[105];
int dp[110];
//若a[i]大于dp的末位数,直接加在后面
//若不是,查找第一个大于value的位置
int FindPosition(int b[],int value,int left,int length)
{
    if(b[length]<value)
        return length+1;
    else//否则进行二分查找
    {
         int mid;
         while(left<=length)
         {
             mid=(left+length)/2;
             if(b[mid]==value)
                 return mid;
             else if(b[mid]<value)
                 left=mid+1;
             else
                 length=mid-1;
         }
    }
}
int main()
{
    int n;
    cin>>n;
    int i,j;
    for(i=0;i<n;i++)
    {
        cin>>a[i];
    }
    dp[1]=a[0];
    int length=1;
    for(i=1;i<n;i++)
    {
        int position=FindPosition(dp,a[i],1,length);
        dp[position]=a[i];
        length=max(length,position);
    }
    cout<<length<<endl;
    for(int j=1;j<=length;j++)
        cout<<dp[j]<<" ";
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章