動態規划入門(1):最長遞增子序列


__________________________工作學習之余,一邊聽歌,一邊推敲。人生一大快事!

不斷修煉自己讀代碼的能力。

眉眼初抬,且看最長遞增子序列。

設長度為N的數組為,則假定以結尾的數組序列的最長遞增子序列長度為L(j),則

也就是說,我們需要遍歷在j之前的所有位置i(從0到j-1),找出滿足條件a[i]<a[j]的L(i),求出max(L(i))+1即為L(j)的值。

最后,我們遍歷所有的L(j)(從0到N-1),找出最大值即為最大遞增子序列。時間復雜度為O(N^2)。

例如給定的數組為{5,6,7,1,2,8},則L(0)=1, L(1)=2, L(2)=3, L(3)=1, L(4)=2, L(5)=4。所以該數組最長遞增子序列長度為4,序列為{5,6,7,8}。

my codes:

 

#include<bits/stdc++.h>
#define len(a) (sizeof(a) / sizeof(a[0])) 
//求取數組長度優秀預定義
using namespace std;
int lis(int a[],int len)
{
    int dp[len];
    for(int i=0;i<len;i++) dp[i]=1;

    for(int j=1;j<len;j++)
    {
        for(int i=0;i<j;i++)
        {
            if(a[i]<a[j] && dp[j]<dp[i]+1)
                dp[j]=dp[i]+1;
        }
    }

    int max=0;
    for(int j=0;j<len;j++)
    {
        if(dp[j]>max) max=dp[j];
    }
    return max;
}
int main()
{
    int a[]={5,6,7,1,2,8};
    int res=lis(a,len(a));
    cout<<res<<endl;
    return 0;
}

 my codes2:

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int n;
    cin>>n; 
    int tmp;
    vector<int> queue;
    vector<int> dp(n,1);
    for(int i=0;i<n;i++)
    {
        cin>>tmp;
        queue.push_back(tmp);
    }
    for(int i=1;i<n;i++)
    {
        for(int j=0;j<i;j++)
        {
            if(queue[i]>queue[j] && dp[i]<dp[j]+1) 
                    dp[i]=dp[j]+1;
        }
    }

    int max=0;
    for(int i=0;i<n;i++)
    {
        if(dp[i]>max) max=dp[i]; //注意細節哦,行百里者半九十!是>號哦! 
    }
    cout<<max<<endl;
    return 0;
}

 

 牛刀小試:

https://www.nowcoder.com/practice/6d9d69e3898f45169a441632b325c7b4?tpId=37&tqId=21247&tPage=2&rp=&ru=%2Fta%2Fhuawei&qru=%2Fta%2Fhuawei%2Fquestion-ranking

 

 

參考:

https://blog.csdn.net/u013178472/article/details/54926531

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM