最长上升子序列

合唱队形题

题目分析 :分别求最长上升和下降子序列。

题目分析 :这道题差不多是个水题了,不过我在做题的被误导了,虽然结果正确却超时了。我们用上升子序列的时间复杂度是:O(n*n);

题目收获 :需要对时间复杂和空间复杂度进行深刻的重新理解。

AC代码 :

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define maxn 105
using namespace std;
int d[maxn],b[maxn],num;
int pepo[maxn];

int main()
{
    //freopen("in.txt", "r", stdin);
    scanf("%d", &num);
    memset(d, 0, sizeof(d));
    memset(b, 0, sizeof(b));
    for (int i = 1; i <= num; i++)
        scanf("%d", &pepo[i]);
    for (int i = 2; i <= num; i++)
        for (int j = 1; j < i; j++)
            if (pepo[i] > pepo[j])
                d[i] = max(d[i], d[j] + 1);
    for (int i = num - 1; i >= 1; i--)
        for (int j = num; j > i; j--)
            if (pepo[i] > pepo[j])
                b[i] = max(b[i], b[j] + 1);
    int ans = 0;
    for (int i = 1; i <= num; i++)
        ans = max(ans, b[i] + d[i]);
    printf("%d
", num - ans - 1);
        return 0;
}
View Code

然,我在参考他人的代码时发现,还存在一种时间复杂度为O(n*logn)的算法,这就给我们一个面对大量数据时,不用担心超时的问题。假设一组数p[]={2 1 5 3 6 4 8 9 7} ,现在求它的上升子序列。

我们用b[0]存p[0],即b[0]=2;

然后发现1<2,所以b[0]=p[1]=1;被替换掉了。

我们知道5>1,b[0+1]=b[1]=p[2]=5;此时b[]={1,5};

到了p[3]=3<5;我们继续替换b[2]=p[3]=3;此时b[]={1,3};

又到6>3,b[2+1]=b[3]=p[4]=6;此时b[]={1,3,6};

一次推下去知道,b[]={1,3,4,8,9}

最后发现:7<9;所以我们8替换为7.(这样做的目的是为了在后面加数字的时候任可以保持正确性)

代码实现:二分法。

#include <iostream>
#include <algorithm>

using namespace std;
const int maxn = 105;
int fup[maxn],fdown[maxn],p[maxn];

int search(int x, int y,int num)
{
    int mid = 0;
    while (x < y)
    {
        if (num > fup[mid = (x + y) >> 1])//二分求num值应该在的位置
            x = mid + 1;
        else
            y = mid;
    }
    return x;
}

int main()
{
    freopen("in.txt", "r", stdin);
    int t, k = 0;
    while (cin >>t && t)
    {
        memset(fup, 0, sizeof(fup));
        memset(fdown, 0, sizeof(fdown));
        memset(p, 0, sizeof(p));
        for (int i = 0; i < t; i++)
            scanf("%d", &p[i]);
        int j = 1;//初始化位置;
        for (int i = 0; i < t; i++)//从0开始遍历
        {
            if (fup[k = search(0, j - 1, p[i])] >= p[i])
                fup[k] = p[i];
            else
                fup[j++] = p[i];
        }

    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/7750-13/p/7395663.html