zoukankan      html  css  js  c++  java
  • 最长上升子序列 和 最长不下降子序列

    最长上升子序列:是严格上升的,a<b<c<d这样的,即为严格单调递增,用lower_bound

    lower_bound:返回序列中大于等于key值的第一个数

    比如说序列 1 2 3 4 5,key值为3,使用lower_bound返回第三个数

    最长不下降子序列:不是严格上升,可以存在多个数相等的情况,用upper_bound

    upper_bound:返回序列中严格大于key值的第一个数

    比如说序列1 2 3 4 5,key值为3,使用upper_bound返回第四个数

    Hdu 1950 求最长上升子序列

     1 #include<iostream>  
     2 #include<cstdio>  
     3 #include<cstring> 
     4 #include <cmath> 
     5 #include<stack>
     6 #include<vector>
     7 #include<map> 
     8 #include<set>
     9 #include<queue> 
    10 #include<algorithm>  
    11 using namespace std;
    12 
    13 typedef long long LL;
    14 const int INF = (1<<30)-1;
    15 const int mod=1000000007;
    16 const int maxn=1000005;
    17 
    18 int a[maxn],f[maxn];
    19 int n;
    20 
    21 int main(){
    22     int T;
    23     scanf("%d",&T);
    24     while(T--){
    25         scanf("%d",&n);
    26         for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    27         
    28         int len=1;
    29         f[1]=a[1];
    30         for(int i=2;i<=n;i++){
    31             if(a[i]>f[len]) f[++len]=a[i];
    32             else{
    33                 int pos=lower_bound(f+1,f+len+1,a[i])-f;//lower_bound返回序列中大于等于key值的第一个数 
    34                 f[pos]=a[i];
    35             }
    36         }
    37         printf("%d
    ",len);
    38     }
    39     return 0;
    40 }
    View Code

    Hdu 5256

    题意:给出一个数列,a1,a2,a3,a4,---,an,现在需要修改尽量少的元素,使得这个序列严格递增

    因为:   a[i]<a[i+1]

    又因为   a[i],a[i+1]都是整数

    所以     a[i+1]-1>=a[i]

    变形得   a[i+1]-(i+1)>=a[i]-i

    令       b[i]=a[i]+1

    所以可以求出b[i]的最长不下降子序列,再用n-len即为需要改变的最少的个数

    学习的这一篇:http://blog.csdn.net/greatwjj/article/details/14518345

     1 #include<iostream>  
     2 #include<cstdio>  
     3 #include<cstring> 
     4 #include <cmath> 
     5 #include<stack>
     6 #include<vector>
     7 #include<map> 
     8 #include<set>
     9 #include<queue> 
    10 #include<algorithm>  
    11 using namespace std;
    12 
    13 typedef long long LL;
    14 const int INF = (1<<30)-1;
    15 const int mod=1000000007;
    16 const int maxn=1000005;
    17 
    18 int a[maxn],f[maxn];
    19 
    20 int main(){
    21     int T;
    22     scanf("%d",&T);
    23     int kase=0;
    24     while(T--){
    25         int n;
    26         scanf("%d",&n);
    27         for(int i=1;i<=n;i++) {
    28             scanf("%d",&a[i]);
    29             a[i]=a[i]-i;
    30         }
    31         
    32         int len=1;
    33         f[1]=a[1];
    34         for(int i=2;i<=n;i++){
    35             if(a[i]>=f[len]) f[++len]=a[i];//这里也和求最长上升子序列不同,是大于等于 
    36             else{
    37                 int pos=upper_bound(f+1,f+len+1,a[i])-f;//upper_bound返回的是序列中严格大于key值的第一个数 
    38                 f[pos]=a[i];
    39             }
    40         }
    41         printf("Case #%d:
    ",++kase);
    42         printf("%d
    ",n-len);        
    43     }
    44     return 0;
    45 }
    View Code
  • 相关阅读:
    Linux常用命令-centos
    USACO 2006 Open, Problem. The Country Fair 动态规划
    USACO 2007 March Contest, Silver Problem 1. Cow Traffic
    USACO 2007 December Contest, Silver Problem 2. Building Roads Kruskal最小生成树算法
    USACO 2015 February Contest, Silver Problem 3. Superbull Prim最小生成树算法
    LG-P2804 神秘数字/LG-P1196 火柴排队 归并排序, 逆序对
    数据结构 并查集
    浴谷国庆集训 对拍
    1999 NOIP 回文数
    2010 NOIP 普及组 第3题 导弹拦截
  • 原文地址:https://www.cnblogs.com/wuyuewoniu/p/4543887.html
Copyright © 2011-2022 走看看