zoukankan      html  css  js  c++  java
  • pku1631 Bridging signals

    http://poj.org/problem?id=1631

    DP 最长上升子序列

    最长上升子序列,因为n很大(n<40000),我开始写的O(n^2)的算法超时了。。。

    学了一下O(n*logn)的方法,dp[i]表示当前状态下,所有长度为i的子序列中,末尾元素最小的那个子序列,的末尾元素值。

    例如序列:a[6]:(1,3,5,4,6,2)

    考虑到前6个元素的时候

    长度为3的子序列有:(1,3,5)  (1,3,4)  (1,3,6)  (3,5,6)  (3,4,6)  那么dp[3] = 4;

    长度为4的子序列有:(1,3,5,6)  (1,3,4,6)  那么dp[4] = 6;

    开始时dp数组为空,依次遍历原序列a[n],对每一个当前元素a[i],都要更新一次dp数组

    更新规则:从已有的dp数组中,找到第一个比当前元素a[i]大的元素,返回下标j, 然后更新 dp[j] = a;

    到此,总体还是一个O(n*n)的算法,

    但因为dp数组是单调的,可以用二分查找,使更新操作变成O(logn)

    也可以从后向前查找dp数组,找到后用break;节省大概一半的时间,虽然是O(n^2),也可以A掉本题。。。

    O(n*logn)代码:

     1 #include <stdio.h>
     2  
     3  int n, a[43210], dp[43210];
     4  const int maxint = (1<<31)-1;
     5  
     6  int bs(int l ,int r, int x)
     7  {
     8      int m;
     9      while(l < r)
    10      {
    11          m = (l + r)>>1;
    12          if(dp[m] < x)
    13          {
    14              l = m + 1;
    15          }
    16          else
    17          {
    18              r = m;
    19          }
    20      }
    21      return l;
    22  }
    23  
    24  int LIS()
    25  {
    26      int i, j, maxn = 1;
    27      dp[0] = 0;
    28      dp[1] = maxint;
    29      for(i=1; i<=n; i++)
    30      {
    31          j = bs(0, maxn+1, a[i]);
    32          dp[j] = a[i];
    33          if(j > maxn)
    34          {
    35              maxn ++;
    36              dp[maxn+1] = maxint;
    37          }
    38      }
    39      return maxn;
    40  }
    41  
    42  int main()
    43  {
    44      int t, i;
    45      scanf("%d", &t);
    46      while(t-- && scanf("%d", &n))
    47      {
    48          for(i=1; i<=n && scanf("%d", a+i); i++);
    49          printf("%d\n", LIS());
    50      }
    51      return 0;
    52  }
  • 相关阅读:
    php的webservice的soapheader认证问题
    训练与解码
    ajax 图片上传
    js倒计时
    数据分析有价值的博客
    [Luogu P5675][GZOI2017]取石子游戏
    [BZOJ4558/LOJ2025/Luogu3271][GZOI2016/JLOI2016/SHOI2016]方
    [BZOJ4557/LOJ2024/Luogu3267][GZOI2016/JLOI2016/SHOI2016]侦察守卫
    PKUWC2019游记
    随机带权选取文件中一行 分类: linux c/c++ 2014-06-02 00:11 344人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/yuan1991/p/pku1631.html
Copyright © 2011-2022 走看看