最長不下降子序列的兩種解法

第一種: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]<<" ";
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章