算法导论—最长递增子序列

华电北风吹
日期:2016/2/20

问题描述:
例如数组arr=[1,5,8,2,3,4]的最长递增子序列是1,2,3,4

动态规划求解。对于数组中的每个元素,从前往后计算每个元素的状态——到这个元素为止所构成的最长递增子序列。时间复杂度 Θ(n2)
参考代码:

#include <iostream>
#include <fstream>
using namespace std;

#define MAXLENGTH 10

int LongestIncreasingSubsequence(int arr[], int n, int state[], int line[])
{
    int path[MAXLENGTH];
    for (int i = 0; i < n; ++i)
    {
        path[i] = i;
    }
    state[0] = 1;
    for (int i = 1; i < n; ++i)
    {
        state[i] = 1;
        for (int j = 0; j < i; ++j)
        {
            if (arr[i] >= arr[j] && state[j] + 1 > state[i])
            {
                state[i] = state[j] + 1;
                path[i] = j;
            }
        }
    }
    int max = 0;
    int end = -1;
    for (int i = 0; i < n; ++i)
    {
        if (state[i] > max)
        {
            max = state[i];
            end = i;
        }
    }
    int i = 1;
    line[0] = arr[end];
    while (path[end] != end)
    {
        line[i++] = arr[path[end]];
        end = path[end];
    }
    return max;
}
int main()
{
    ifstream in(".\\input.txt");
    cin.rdbuf(in.rdbuf());

    int n;
    int X[MAXLENGTH];
    int c[MAXLENGTH];
    int line[MAXLENGTH];
    while (cin >> n, n != 0)
    {
        for (int i = 0; i < n; ++i)
        {
            cin >> X[i];
        }
        int max = LongestIncreasingSubsequence(X, n, c, line);
        cout << "Longest Increasing Subsequence's Length: " << max << endl;
        for (int i = max - 1; i >= 0; --i)
        {
            cout << line[i]<<" ";
        }
        cout << endl;
    }
}

网上见了一个比较巧妙的算法,代码如下(这里让我想到了快排的那种与这个特别像的实现方式)。目前下面的算法复杂度仍旧是 Θ(n2) ,但是对于内层循环的查找进行二分优化,可以使得复杂度降低为 Θ(nlogn)

#include <stdio.h>
#include<string.h>
char str[10001];
int main()
{
    int T, i, j;
    int len, ans;
    scanf("%d", &T);
    while (T--)
    {
        memset(str, 0, sizeof(str));
        scanf("%s%*c", str);
        len = strlen(str);
        ans = 0;
        for (i = 0; i < len; i++)
        {
            for (j = 0; j < ans; j++)
            {
                if (str[j] >= str[i])
                {
                    str[j] = str[i];
                    break;
                }
            }
            if (j == ans)
            {
                str[j] = str[i];
                ans++;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

你可能感兴趣的:(算法导论—最长递增子序列)