zoukankan      html  css  js  c++  java
  • poj 2533 Longest Ordered Subsequence 最长递增子序列

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4098562.html

    题目链接:poj 2533 Longest Ordered Subsequence 最长递增子序列

    使用$len[i]$表示序列中所有长度为$i$的递增子序列中最小的第$i$个数的值为$len[i]$。对于序列的第j个数$arr[j]$,在$len$中二分查找,找到最后一个小于$arr[j]$的数$len[k]$,如果$len[k]$是序列$len$中最后的一个数,那么在其尾部添加一个数$arr[j]$,否则另$len[k+1]=arr[j]$,直到遍历完$arr$。时间复杂度为O(nlogn)。

    代码如下:

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <iostream>
     4 #include <cstring>
     5 #include  <vector>
     6 #define     MAXN 1010
     7 using namespace std;
     8 int arr[MAXN];
     9 int n;
    10 int bs(vector<int> &arr,int num)
    11 {
    12     int b = 0, e = arr.size()-1;
    13     int mid;
    14     while( b <= e )
    15     {
    16         mid = (b+e)/2;
    17         if( arr[mid] <= num )
    18         {
    19             b = mid+1;
    20         }
    21         else
    22         {
    23             e = mid-1;
    24         }
    25     }
    26     return b;
    27 }
    28 int solve()
    29 {
    30     if( n == 0 )
    31     {
    32         return 0;
    33     }
    34     vector<int> len;
    35     len.push_back(arr[0]);
    36     for( int i = 1 ; i < n ; i++ )
    37     {
    38         if( len[len.size()-1] < arr[i])
    39         {
    40             len.push_back(arr[i]);
    41         }
    42         else
    43         {
    44             len[bs(len, arr[i])] = arr[i];
    45         }
    46     }
    47     return len.size();
    48 }
    49 int main(int argc, char *argv[])
    50 {
    51     while( scanf("%d", &n) != EOF )
    52     {
    53         for( int i = 0 ; i < n ; i++ )
    54         {
    55             scanf("%d", &arr[i]);
    56         }
    57         printf("%d
    ", solve());
    58     }
    59 }
    View Code

    同样还有一种$O(n^2)$的动态规划算法。使用$dp[i]$表示到第$i$个数最长的递增子序列的长度。每次用j从0到$i-1$遍历数组,如果发现arr[j]<arr[i],则说明其长度可以加1,最终取最大的长度作为dp[i],即:

    egin{equation}
    dp[i] = min(dp[j])+1,(j<i,arr[j]<arr[i])
    end{equation} 

    代码如下:

     1 #include <cstdio>
     2 #include <cstdlib>
     3 #include <iostream>
     4 #include <cstring>
     5 #define     MAXN 1010
     6 using namespace std;
     7 int dp[MAXN];
     8 int arr[MAXN];
     9 int n;
    10 int solve()
    11 {
    12     if( n == 0 )
    13     {
    14         return 0;
    15     }
    16     memset(dp, 0, sizeof(dp));
    17     dp[0] = 1;
    18     int res = 1;
    19     for( int i = 1 ; i < n ; i++ )
    20     {
    21         int tmp = 0;
    22         for( int j = 0 ; j < i ; j++ )
    23         {
    24             if( arr[i] > arr[j] )
    25             {
    26                 tmp = max(tmp, dp[j]);
    27             }
    28         }
    29         dp[i] = tmp+1;
    30         res = max(res, dp[i]);
    31     }
    32     return res;
    33 }
    34 int main(int argc, char *argv[])
    35 {
    36     while(scanf("%d", &n) != EOF)
    37     {
    38         for( int i = 0 ; i < n ; i++ )
    39         {
    40             scanf("%d", &arr[i]);
    41         }
    42         printf("%d
    ",solve()); 
    43     }
    44 }
    View Code
  • 相关阅读:
    剑指offer03-04
    五大算法-1.回溯法
    linux与操作系统(1)- 用户接口
    python中的装饰器
    mysql 创建数据库,用户并给用户设置权限
    centOS6.5 桌面状态栏消失 解决
    centOS linux 远程Mysql 记录之root用户密码丢失
    XStream.toXML() 简单两种使用实例
    FileInputStream和FileOutStream 简单的使用实例;
    orale 行转列或者 字符拼接函数 wmsys.wm_concat()函数 /instr(listagg(name,';') within group (order by o.srclinkedid)
  • 原文地址:https://www.cnblogs.com/jostree/p/4098562.html
Copyright © 2011-2022 走看看