hdu5489(删除一段后的最长上升子序列长度)LIS

来源:互联网 发布:https的默认端口 编辑:程序博客网 时间:2024/06/05 07:06


#include<bits/stdc++.h>using namespace std;const int maxn = 1e5+5;int a[maxn];int g[maxn];int f[maxn];int h[maxn];int c[maxn]; int d[maxn]; const int INF = 0x3f3f3f3f;//#define LOCALint main(){#ifdef LOCAL    freopen("in.txt","r",stdin);#endif    int T; scanf("%d",&T);    for(int ks = 1; ks <= T; ks++){        int N,L,k,kk; scanf("%d%d",&N,&L);        for(int i = 0; i < N; i++) scanf("%d",a+i);        int s=0;//  fill(g,g+N-L,INF);//        fill(d,d+N-L,0);//        for(int i=0;i<N-L;++i){//          k = lower_bound(g,g+i+1,a[i])-g;//            h[i] = k+1;  //以i点结尾的LIS长度//            g[k] = a[i]; //LIS长度为k+1的最小末位值(递增),没有该长度的会返回-1061109567或者1061109567 //            d[k] = max(d[k],a[i]);//LIS长度为k+1的最大末位值(递增)//        }        fill(g,g+N-L,INF);    //    fill(c,c+N-L,INF);        for(int i = N-1; i >= L; i--){            k = lower_bound(g,g+N-i-1,-a[i])-g;            f[i] = k+1;  //从i点开始往后的LIS长度            g[k] = -a[i];//LIS长度为k+1的最大首位值*-1(递增),没有该长度的会返回-1061109567或者1061109567//c[k] = min(c[k],a[i]); //LIS长度为k+1的最小首位值(递增)         }        f[N]=0;        a[N]=INF;        fill(g,g+N-L,INF);        for(int i=L;i<=N;++i){        kk = lower_bound(g,g+i-L,a[i])-g; s=max(s,(kk-1)+1+f[i]);k = lower_bound(g,g+i-L,a[i-L])-g; g[k] = a[i-L];//以i点结尾的LIS长度为k+1的最小末位值(递增),没有该长度的会返回-1061109567或者1061109567}       printf("Case #%d: %d\n",ks,s);    }    return 0;}

另一题,【输出字典序最小的LIS】

#include<bits/stdc++.h>  using namespace std;  const int maxn = 1e5+5;  int a[maxn];  int g[maxn];  int f[maxn];  int h[maxn];  int c[maxn];   int d[maxn];   const int INF = 0x3f3f3f3f;  int main()  {      int N,L,k,kk;     int t;    scanf("%d",&t);    while(t--){scanf("%d",&N);        for(int i = 0; i < N; i++) scanf("%d",&a[i]);          int s=0;          fill(g,g+N,INF); //fill(d,d+N,INF);           int maxx=0;        for(int i=0;i<N;++i){              k = lower_bound(g,g+i+1,a[i])-g;              h[i] = k+1;  //以i点结尾的LIS长度              g[k] = a[i]; //LIS长度为k+1的末位值(递增),没有该长度的会返回-1061109567或者1061109567   //        d[k] = min(d[k],a[i]);//LIS长度为k+1的最大末位值(递增),但用在这道题并不合适(因为并不一定是同一个序列) maxx=max(maxx,h[i]);} int p=maxx;for(int i=N-1;i>=0;--i){if(h[i]==maxx){d[maxx]=a[i];maxx--;}}  printf("%d\n",p); for(int i=1;i<=p-1;++i){ printf("%d ",d[i]); } printf("%d\n",d[p]); }    return 0;  } /*274 3 3 2 7 9 6/3/2 7 9107 2 9 10 3 8 10 6 5 4/4/2 3 8 10*/

另一题,【最少不增子序列个数】=最长递增子序列长度

#include<bits/stdc++.h>  using namespace std;     const int maxn = 110000;  int f[maxn], cnt;  int main()  {      for(int n; ~scanf("%d", &n);) {          f[0] = 30001;          cnt = 0;          for(int i = 0, a; i < n; i++) {              scanf("%d", &a);              if(a > f[cnt]) f[++cnt] = a;              else{            int p=lower_bound(f,f+cnt+1,a)-f; f[p] = a;  }        }          printf("%d\n", cnt+1);      }      return 0;  }  

0 0
原创粉丝点击