LIS/LCS的几种写法(最长上升子序列/最长公共子序列)

LIS有三种写法,此文章仅写出两种复杂度分别为(n^2)和(nlogn)

第一种写法O(n^2)

    int num[1000], n,out=0;//n为字母个数,num存放数字,out为最长上升子序列的长度
    int dp[1000];//dp存放该数字为最后一个数字的时候最长上升子序列的长度
    cin >> n;
    for (int i = 0; i < n; i++)//输入数字
    {
        cin >> num[i];
    }
    for (int i = 0; i < n; i++)//初始化dp数组
    {
        dp[i] = 1;
    }
    for (int i = 0; i < n; i++)
    {
        for (int f = 0; f < i; f++)
        {
            if (num[f] < num[i])//当num[i]大于num[f]时即上升
            {
                dp[i] = max(dp[i], dp[f] + 1);
            }
        }
        out = max(out, dp[i]);
    }
    cout << out << endl;

第二种写法O(nlogn)

    int num[1000], n, len;
    int dp[1000];
    cin >> n;
    for (int i = 1; i <= n; i++)
    {
        cin >> num[i];
    }
    dp[1] = num[1];
    len = 1;
    for (int i = 2; i <= n; i++)
    {
        if (num[i] > dp[len])//有数字比当前末尾的数字大则len++
        {
            dp[++len] = num[i];
        }
        else
        {
            int l = 0, r = len, mid;
            while (l <= r)//二分
            {
                mid = (l + r) >> 1;
                if (dp[mid] >= num[i])
                {
                    r = mid - 1;
                }
                else
                {
                    l = mid + 1;
                }
            }
            dp[l] = num[i];
        }
    }
    cout << len << endl;

LCS利用动态规划实现

    int dp[100][100] = { 0 };
    string x, y;
    cin >> x >> y;
    for (int i = 0; i < x.length(); i++)
    {
        for (int f = 0; f < y.length(); f++)
        {
            if (x[i] == y[f])
            {
                dp[i + 1][f + 1] = dp[i][f] + 1;
            }
            else
            {
                dp[i + 1][f + 1] = max(dp[i][f + 1], dp[i + 1][f]);
            }
        }
    }
    cout << dp[x.length()][y.length()] << endl;

 

posted @ 2020-05-26 22:11  绝军师  阅读(204)  评论(0编辑  收藏  举报