最长单调递增子序列

问题:

设计一个O(n^2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。

方法一:最长公共子序列。

思路:1:将数组a复制到b;

           2:对b排序;

           3:对数组b去重(注意去重是必要的,因为要求单调递增),这里利用hash表去重。  

           4:求a, b数组的最长公共子序列。

           求最长公共子序列方法见 https://blog.csdn.net/m0_38015368/article/details/79835163

 代码:

#include <bits/stdc++.h>
using namespace std;
int a[1024]; //原数组
int b[1024]; //排序后数组
int ans[1024][1024]; //记录 c[i][j] 的值是有哪个子问题得到
int c[1024][1024]; //最长子序列长度
int n; //数组长度
int m; //去重后的长度
void LCS(int i, int j)
{
    if(i == 0 || j == 0)
        return;
    else if(ans[i][j] == 1)
    {
        LCS(i - 1, j - 1);
        cout << a[i] << " ";
    }
    else if(ans[i][j] == 2)
    {
        LCS(i - 1, j);
    }
    else
    {
        LCS(i, j - 1);
    }
}
void LCSLegth()
{
    memset(ans, 0, sizeof(ans));
    memset(c, 0, sizeof(c));
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            if(a[i] == b[j])
            {
                c[i][j] = c[i - 1][j - 1] + 1;
                ans[i][j] = 1;
            }
            else if(c[i - 1][j] > c[i][j - 1])
            {
                c[i][j] = c[i - 1][j];
                ans[i][j] = 2;
            }
            else
            {
                c[i][j] = c[i][j - 1];
                ans[i][j] = 3;
            }
        }
    }
}
void HashTable()
{
    int max_ = b[n];
    m = 0;
    int *p = new int(max_);
    memset(p, 0, sizeof(p));
    for(int i = 1; i <= n; ++i)
    {
        p[b[i]] = 1;
    }
    memset(b, 0, sizeof(b));
    for(int i = 0; i <= max_; ++i)
    {
        if(p[i] == 1)
            b[++m] = i;
    }
    delete []p;
    p = NULL;

}
void solve()
{
    sort(b + 1, b + n);
    HashTable(); //去重
//    for(int i = 1; i <= m; ++i)
//        cout << b[i] << " ";
//    cout << endl;
    LCSLegth();
    LCS(n, m);
}
void inPut()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
    {
        scanf("%d", &a[i]);
        b[i] = a[i];
    }
}
int main()
{
    inPut();
    solve();
}

方法二

猜你喜欢

转载自blog.csdn.net/m0_38015368/article/details/80036948
今日推荐