题意:给出一个从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); } }