• 1134 最长上升子序列 (序列型 DP)


    思路: 由于一般的动态规划时间复杂度是O(n^2)(哈哈哈哈 第一次用的就是这个!)用在这里由于n最大为50000 所以会超时 到这里我们可以用一个数组来动态维护这个最长上升的子序列,将你要输入的子序列一个一个按升序存入数组 如果发现当前要存入的数字x比数组最后一个还要大 那么直接存入数组,否则就将数组中按升序第一个大于x的数 用x替换掉(这里的替换我们可以用二分搜索来进行) 由于二分搜索的时间复杂度是log(n) 所以总的时间复杂度为O(n log(n) ); 下面举个例子

      例如 -6 4 -2 10 5 ,我们假设用p数组来存储这个序列 那么 p[0] = -6; 我们发现4 比-6大我们就直接将之存入 则 p[1] = 4,现在到 -2 我们用将数组总第一个大于-2的数用-2替换掉 则 p[1] = -2 ,现在p[]= ( -6,-2 ); 之后再用同样的方法 最后的结果是p[] = ( -6 , -2 , 5 ), 这里可以得知 (-6,-2,10) 的长度与前面的答案一致 但是因为5比10 小 所以如果后面还有数可以继续拓展的话 很明显 5 之后可以存的更多的数(  好像有点啰嗦!还是直接上代码吧) 

     1 /*
     2 //我们先来看一下第一次的超时代码 
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<cstring>
     6  
     7 using namespace std;
     8 typedef long long LL;
     9 const LL maxn = 50005;
    10 LL dp[maxn];
    11 LL m[maxn];
    12 LL n;
    13 int main()
    14 {
    15     cin>>n;
    16     for(int i=1;i<=n;i++)
    17     {
    18         cin>>m[i];
    19         dp[i] = 1;
    20     }
    21     for(int i=2;i<=n;i++)
    22         for(int j=i;j>=1;j--)
    23             if(m[i]>m[j])
    24                 dp[i] = max(dp[i],dp[j]+1);
    25     LL ans = 0;
    26     for(int i=1;i<=n;i++)
    27         ans = max(ans,dp[i]);
    28     cout<<ans<<endl;
    29     return 0;
    30 }
    31 
    32 */
    33 
    34 //优化后的代码 
    35 #include<iostream>
    36 #include<algorithm>
    37 #include<cstring>
    38 
    39 using namespace std;
    40 const int maxn = 50005;
    41 int p[maxn],a[maxn];
    42 int n,len = 0;
    43 int main()
    44 {
    45     cin>>n;
    46     for(int i=0;i<n;i++)
    47         cin>>a[i];
    48     p[0] = a[0];
    49     for(int i=1;i<n;i++)
    50     {
    51         if(a[i]>p[len])//当前数大于数组末尾的数 直接存入 
    52             p[++len] = a[i];
    53         else
    54         {
    55             int pos = upper_bound(p,p+len,a[i]) - p;
    56             p[pos] = a[i];//将第一个大于当前数的目标用当前数替换掉 
    57         }
    58     }
    59     cout<<len + 1<<endl;//由于len是从0开始 所以答案要加一 
    60     return 0;
    61 }
  • 相关阅读:
    静态内部类与非静态内部类之间的访问
    面向对象蚂蚁爬杆的问题
    关于Clone 的方法使用
    关于谁来参加会议这个题目的卫条件
    String类的基本用法与注意点,StringBuffer类的用法
    Smarty模板Windows下写代码 放到CentOS6.5无法正确解析
    [转]Linux(centOS6.5)下SVN的安装、配置及开机启动
    [转]Centos6.5使用yum安装mysql—配置MySQL允许远程登录
    [转]-bash: wget: command not found的两种解决方法
    [转]VMware 出现下述错误: Application failure. hr=0x80040101:Failed to initialize virtual machine.
  • 原文地址:https://www.cnblogs.com/wangrunhu/p/8584498.html
Copyright © 2020-2023  润新知