最長不下降子序列(上升同理)

最長不下降就是一條個數最多的,不下降(可以相等)的序列
比如
1 1 1 1
最長不下降子序列就是4

13,7,9,16,38,24,37,18,44,19,21,22,63,15
最長不下降子序列就是7,9,16,18,19,21,22,63

下面我們來分析一下思路

我們使用一個二維數組s[10][3],每一行的第一個代表個數,第幾個,第二個代表他自身數據。第三行代表從他開始的不下降子序列的長度,第四個代表從他開始的不下降子序列的下一個元素的座標

下面我們使用上面的例子來詳細說明一下算法過程
在這裏插入圖片描述

有這樣一組數據,第一行是個數,第二行是本身數據

我們採用逆序的方法,從最後一個開始
在這裏插入圖片描述
從15這個數開始的不下降子序列長度是1,下一個數據下標是0

在這裏插入圖片描述

63>15,所以63的下一行數據是1,最後一行數據是0
22<63,22下一行數據應該是2,繼承63的1

在這裏插入圖片描述

21<22,繼承22的2,21數據的下一行是3,最後一行是12

在這裏插入圖片描述

依此類推,就可以得到所有數據
在這裏插入圖片描述

下面是代碼

#include<iostream>
using namespace std;
int main()
{
    int s[1100][20],i,j,max,n=1,l,k;
    while(cin>>s[n][1])
    {
        s[n][2]=1,s[n][3]=0;
        n++;
    }
        n--;//數字個數
        for(i=n-1;i>=1;i--)
        {
            l=0,k=0;//k是下一個數的下標,l是長度
            for(j=i+1;j<=n;j++)
            {
                if(s[i][1]<=s[j][1]&&s[j][2]>l)
                {
                    l=s[j][2];
                    k=j;
                }
            } 
            if(l>0)
            {
                s[i][2]=l+1;//最長子序列長度 
                s[i][3]=k;//下一項的下標 
            }
        }
        k=1;
        for(i=2;i<=n;i++)
        {
            if(s[i][2]>s[k][2]) k=i;
        }
        cout<<"max="<<s[k][2]<<endl;
        cout<<s[k][1];
        k=s[k][3];
        while(k!=0)
        {
            cout<<" "<<s[k][1];
            k=s[k][3];
        }
    return 0;
}

最長不上升子序列同理,小於號換成大於號就行啦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章