Bridging signals ZOJ 3627 POJ1631 HDU1950

题意:给出一个从1-n的数字排列,求最长上升子序列长度。

直接说解法吧。新开一个数组d,d[i]表示的是能构成长度为i的上升子序列的在原序列中最后的那个数值。程序的主要过程:当循环到第i个的时候,如果原序列中的第i个数值大于之前d中保存的上升序列中长度最长的那个最后的值,那么,就把当前记录的最长的子序列的长度+1,然后把这个值加到d的末尾;如果不大于,那么就从前面二分找到这个值,d中的序列一定是有序的,找到d总刚刚大于它的那个值,替换掉。

#include <cstdio>

#include <string.h>

#include <algorithm>

using namespace std;

int main(){

    int cir,n,ans;

    int d[40000];

    int a[40000];

    scanf("%d",&cir);

    for(int i=1;i<=cir;i++){

        scanf("%d",&n);

        for(int j=1;j<=n;j++){//init

            scanf("%d",&a[j]);

        }

        d[0]=0;

        ans=1;d[1]=a[1];

        int temp;

        for(int j=2;j<=n;j++){

            if(a[j]>d[ans])d[++ans]=a[j];

            else {

                temp=lower_bound(d+1,d+ans+1,a[j])-d;

				//从第一个开始;最后要-d

                d[temp]=a[j];

            }

        }

        printf("%d\n",ans);

}

}

  

  

你可能感兴趣的:(Signal)