最長xx子序列

最長上升子序列


最長公共子序列


最長上升子序列

樸素算法 O(n*n)

dp[i]表示以a[i]爲末尾的最長上升子序列的長度

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 100010;
const int inf = 0x3f3f3f3f;
int a[maxn],dp[maxn];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i = 0;i<n;i++)
        {
            scanf("%d",&a[i]);
            dp[i] = 1;
        }
        int ans = 0;
        for(int i = 1;i<n;i++)
        {
            for(int j = 0;j<i;j++)
                if(a[j] < a[i])
                    dp[i] = max(dp[i],dp[j] + 1);
            ans = max(ans,dp[i]);
        }
        printf("%d\n",ans);
    }
}



O(nlogn)

dp[i] = 長度爲i+1的上升子序列中末尾元素的最小值,直接運用STL 中的lower_bound()很方便

#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxn = 100010;
const int inf = 0x3f3f3f3f;
int a[maxn],dp[maxn];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i = 0;i<n;i++)
        {
            scanf("%d",&a[i]);
            dp[i] = inf;
        }
        for(int i = 0;i<n;i++)
        {
            a[i] = *lower_bound(dp,dp+n,a[i]) = a[i];
        }
        printf("%d\n",lower_bound(dp,dp+n,inf) - dp);
    }
}

最長公共子序列

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
string s1,s2;
int dp[1010][1010];
int main()
{
    while(cin >> s1 >> s2)
    {
        int len1 = s1.length();
        int len2 = s2.length();
        memset(dp,0,sizeof dp);

        for(int i = 1;i<=len1;i++)
        {
            for(int j = 1;j<=len2;j++)
            {
                if(s1[i-1] == s2[j-1])
                {
                    dp[i][j] = dp[i-1][j-1] + 1;
                }
                else
                    dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
            }
        }
        cout<<dp[len1][len2]<<endl;
    }
}




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