zoukankan      html  css  js  c++  java
  • CH895 最长上升子序列 题解报告

    题目传送门

    【题目大意】

    给定一个长度为$n$的序列${a_n}$,求最长上升子序列的长度。

    【思路分析】

    解法一:贪心(maybe?)

    设$f_i$表示长度为$i$的上升子序列末尾数的最小值。

    对于数列中的每一个数$x$,我们要找到最小的$f_i$,并且保证$f_ige x$,更新$f_i=x$。若已有的$f$数组中没有任何一个$f_i$满足$f_ige x$,那么就$f_{max_i+1}=x$。

    然后我们可以发现$f$数组有一个神奇的性质,就是保证单调递增,于是我们可以稍微优化一下?

    解法二:DP

    设$f_i$表示以第$i$个数结尾的最长上升子序列的长度。

    转移方程:$f_i=max{f_j+1}(a_i>a_j&&jin[1,i-1])$,最后的答案为$max{f_i}(iin[1,n])$

     解法三

    应该还有一种解法?但是我不记得了QAQ

    【代码实现】

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define g() getchar()
     7 #define rg register
     8 #define go(i,a,b) for(rg int i=a;i<=b;i++)
     9 #define back(i,a,b) for(rg int i=a;i>=b;i--)
    10 #define db double
    11 #define ll long long
    12 #define il inline
    13 #define pf printf
    14 using namespace std;
    15 int fr(){
    16     int w=0,q=1;
    17     char ch=g();
    18     while(ch<'0'||ch>'9'){
    19         if(ch=='-') q=-1;
    20         ch=g();
    21     }
    22     while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=g();
    23     return w*q;
    24 }
    25 int n,a[1002],f[1002],ans=1;
    26 int main(){
    27     //freopen("","r",stdin);
    28     //freopen("","w",stdout);
    29     n=fr();
    30     go(i,1,n) a[i]=fr();f[1]=a[1];
    31     go(i,2,n){
    32         if(f[ans]<a[i]) {f[++ans]=a[i];continue;}
    33         go(j,1,ans)
    34             if(f[j]>=a[i]) {f[j]=a[i];break;}
    35     }
    36     pf("%d
    ",ans);
    37     return 0;
    38 }
    解法一
     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define g() getchar()
     7 #define rg register
     8 #define go(i,a,b) for(rg int i=a;i<=b;i++)
     9 #define back(i,a,b) for(rg int i=a;i>=b;i--)
    10 #define db double
    11 #define ll long long
    12 #define il inline
    13 #define pf printf
    14 using namespace std;
    15 int fr(){
    16     int w=0,q=1;
    17     char ch=g();
    18     while(ch<'0'||ch>'9'){
    19         if(ch=='-') q=-1;
    20         ch=g();
    21     }
    22     while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=g();
    23     return w*q;
    24 }
    25 int n,a[1002],f[1002],ans=0;
    26 int main(){
    27     //freopen("","r",stdin);
    28     //freopen("","w",stdout);
    29     n=fr();
    30     go(i,1,n) a[i]=fr(),f[i]=1;
    31     go(i,1,n){
    32         go(j,1,i-1) if(a[i]>a[j]) f[i]=max(f[i],f[j]+1);
    33         ans=max(ans,f[i]);
    34     }
    35     pf("%d
    ",ans);
    36     return 0;
    37 }
    解法二
  • 相关阅读:
    Debian 9/Ubuntu 18添加rc.local开机自启的方法
    第一次使用Debian9所遇到的问题
    Open-Falcon注册时点击Sign up按钮没反应
    使用VMware虚拟机里的Ubuntu18.04部署RAID 10磁盘阵列
    Ubuntu18.04下Ansible的基本使用
    Go语言求水仙花数(for循环)
    自研模块加载器(四) 模块资源定位-异步加载
    自研模块加载器(三) module模块构造器设计-模块数据初始化
    自研模块加载器(二) 加载器结构与设计导论
    自研模块加载器(一) 模块系统概述与自定义模块规范书写规定
  • 原文地址:https://www.cnblogs.com/THWZF/p/11542443.html
Copyright © 2011-2022 走看看