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);
}
}

  

  

上一篇:STM32-F0/F1/F2


下一篇:TCP、UDP协议间的区别(转)