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

来源:互联网 发布:网络渗透的危害的对策 编辑:程序博客网 时间:2024/05/17 23:06

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

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

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

#include <iostream>#include <fstream>using namespace std;#define MAXLENGTH 10int 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;}
0 0
原创粉丝点击