• 最长上升子序列(LIS)题目合集


    有关最长上升子序列的详细算法解释在http://www.cnblogs.com/denghaiquan/p/6679952.html

    1)51nod 1134

      一题裸的最长上升子序列,由于N<=50000,n2算法会超时,只能用nlogn算法。

     

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <string>
     6 #include <vector>
     7 #include <map>
     8 #include <set>
     9 #include <queue>
    10 #include <sstream>
    11 #include <algorithm>
    12 using namespace std;
    13 #define pb push_back
    14 #define mp make_pair
    15 #define ms(a, b)  memset((a), (b), sizeof(a))
    16 //#define LOCAL
    17 typedef long long LL;
    18 const int inf = 0x3f3f3f3f;
    19 const int maxn = 50000+10;
    20 const LL mod = 1000000000+7;
    21 int a[maxn];
    22 int dp[maxn];
    23 int Binary_search(int key, int len)
    24 {
    25     int l=1, r=len+1;
    26     while(l<r)
    27     {
    28         int middle = (l+r) >> 1;
    29         if(key>=dp[middle])
    30             l = middle +1;
    31         else
    32             r = middle;
    33     }
    34     return l;
    35 }
    36 int main()
    37 {
    38     #ifdef LOCAL
    39         freopen("input.txt" , "r", stdin);
    40     #endif // LOCAL
    41         int n, len;
    42         scanf("%d", &n);
    43         for(int i=0;i<n;i++)    scanf("%d", &a[i]);
    44         dp[1] = a[0];
    45         len = 1;
    46         for(int i=1;i<n;i++)
    47         {
    48             if(a[i] > dp[len])
    49                 dp[++len] = a[i];
    50             else{
    51                 int j = Binary_search(a[i], len);
    52                 dp[j] = a[i];
    53             }
    54         }
    55         printf("%d
    ", len);
    56     return 0;
    57 }
    View Code

    2)POJ 2533

      裸的最长上升子序列,N<=1000, n2算法可以过。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <string>
     6 #include <vector>
     7 #include <map>
     8 #include <set>
     9 #include <queue>
    10 #include <sstream>
    11 #include <algorithm>
    12 using namespace std;
    13 #define pb push_back
    14 #define mp make_pair
    15 #define ms(a, b)  memset((a), (b), sizeof(a))
    16 //#define LOCAL
    17 typedef long long LL;
    18 const int inf = 0x3f3f3f3f;
    19 const int maxn = 1000+10;
    20 const LL mod = 1000000000+7;
    21 int a[maxn];
    22 int dp[maxn];
    23 int main()
    24 {
    25     #ifdef LOCAL
    26         freopen("input.txt" , "r", stdin);
    27     #endif // LOCAL
    28     int n;
    29     scanf("%d", &n);
    30     for(int i=0;i<n;i++)    scanf("%d", &a[i]);
    31     dp[0]=1;
    32     for(int i=1;i<n;i++)
    33     {
    34         dp[i] = 1;
    35         for(int j=0;j<i;j++)
    36         {
    37             if(a[j]<a[i] && dp[j]+1 > dp[i])
    38                 dp[i] = dp[j] + 1;
    39         }
    40     }
    41     int ans = 0;
    42     for(int i=0;i<n;i++)    ans = max(ans, dp[i]);
    43     printf("%d
    ", ans);
    44     return 0;
    45 }
    View Code

    3)POJ 1631

      一题裸的最长上升子序列,由于N<=50000,n2算法会超时,只能用nlogn算法。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <string>
     6 #include <vector>
     7 #include <map>
     8 #include <set>
     9 #include <queue>
    10 #include <sstream>
    11 #include <algorithm>
    12 using namespace std;
    13 #define pb push_back
    14 #define mp make_pair
    15 #define ms(a, b)  memset((a), (b), sizeof(a))
    16 //#define LOCAL
    17 typedef long long LL;
    18 const int inf = 0x3f3f3f3f;
    19 const int maxn = 40000+10;
    20 const LL mod = 1000000000+7;
    21 int a[maxn];
    22 int dp[maxn];
    23 int Binary_search(int key, int len)
    24 {
    25     int l=1, r=len+1;
    26     while(l<r)
    27     {
    28         int middle = (l+r) >> 1;
    29         if(key>=dp[middle])
    30             l = middle +1;
    31         else
    32             r = middle;
    33     }
    34     return l;
    35 }
    36 int main()
    37 {
    38     #ifdef LOCAL
    39         freopen("input.txt" , "r", stdin);
    40     #endif // LOCAL
    41     int T;
    42     scanf("%d", &T);
    43     while(T--)
    44     {
    45         ms(dp, 0);
    46         ms(a, 0);
    47         int n, len;
    48         scanf("%d", &n);
    49         for(int i=0;i<n;i++)    scanf("%d", &a[i]);
    50         dp[1] = a[0];
    51         len = 1;
    52         for(int i=1;i<n;i++)
    53         {
    54             if(a[i] > dp[len])
    55                 dp[++len] = a[i];
    56             else{
    57                 int j = Binary_search(a[i], len);
    58                 dp[j] = a[i];
    59             }
    60         }
    61         printf("%d
    ", len);
    62     }
    63     return 0;
    64 }
    View Code

    4)POJ 1887

      这题是找最长下不上升子序列。发现n2算法可以过。不过要注意输出。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <string>
     6 #include <vector>
     7 #include <map>
     8 #include <set>
     9 #include <queue>
    10 #include <sstream>
    11 #include <algorithm>
    12 using namespace std;
    13 #define pb push_back
    14 #define mp make_pair
    15 #define ms(a, b)  memset((a), (b), sizeof(a))
    16 //#define LOCAL
    17 typedef long long LL;
    18 const int inf = 0x3f3f3f3f;
    19 const int maxn = 32767+10;
    20 const LL mod = 1000000000+7;
    21 int a[maxn];
    22 int dp[maxn];
    23 int main()
    24 {
    25     #ifdef LOCAL
    26         freopen("input.txt" , "r", stdin);
    27     #endif // LOCAL
    28     int t=1;
    29     while(scanf("%d", &a[0])&&a[0]!=-1)
    30     {
    31         if(t>1) printf("
    ");
    32         int n =1, ans = 0 ;
    33         while(scanf("%d", &a[n])&&a[n]!=-1) n++;
    34         dp[0]  = 1;
    35         for(int i=1;i<n;i++)
    36         {
    37             dp[i] = 1;
    38             for(int j=0;j<n;j++)
    39             {
    40                 if(a[j] > a[i] && dp[j]+1 > dp[i])
    41                     dp[i] = dp[j] + 1;
    42             }
    43         }
    44         for(int i=0;i<n;i++)    ans = max(ans, dp[i]);
    45         printf("Test #%d:
    ",t++);
    46         printf("  maximum possible interceptions: %d
    ", ans);
    47         ms(a, 0);
    48         ms(dp, 0);
    49     }
    50     return 0;
    51 }
    View Code

    5)POJ 1609

      这题同样是最长不上升子序列,不过是2个关键词,先排序一个,再在另一个里面找最长不上升子序列。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <string>
     6 #include <vector>
     7 #include <map>
     8 #include <set>
     9 #include <queue>
    10 #include <sstream>
    11 #include <algorithm>
    12 using namespace std;
    13 #define pb push_back
    14 #define mp make_pair
    15 #define ms(a, b)  memset((a), (b), sizeof(a))
    16 //#define LOCAL
    17 typedef long long LL;
    18 const int inf = 0x3f3f3f3f;
    19 const int maxn = 10000+10;
    20 const LL mod = 1000000000+7;
    21 int a[maxn];
    22 int dp[maxn];
    23 struct node
    24 {
    25     int l, m;
    26 };
    27 bool cmp(node x1, node x2)
    28 {
    29     if(x1.l != x2.l)
    30         return x1.l > x2.l;
    31     return x1.m > x2.m;//当第一个关键字相同的时候,第2个关键字要从大到小排序
    32 }
    33 int main()
    34 {
    35     #ifdef LOCAL
    36         freopen("input.txt" , "r", stdin);
    37     #endif // LOCAL
    38     int n;
    39     while(scanf("%d", &n))
    40     {
    41         if(n == 0) {printf("*
    ");break;}
    42         node blocks[maxn];
    43         for(int i = 0;i < n;i++)    scanf("%d%d", &blocks[i].l, &blocks[i].m);
    44         sort(blocks, blocks+n, cmp);
    45         dp[0] = 1;
    46         for(int i=1;i<n;i++)
    47         {
    48             dp[i] = 1;
    49             for(int j = 0;j<i;j++)
    50             {
    51                 if(blocks[j].m >= blocks[i].m && dp[j] + 1 > dp[i])
    52                     dp[i] = dp[j]+1;
    53             }
    54         }
    55         int ans = 0;
    56         for(int i=0;i<n;i++)    ans = max(ans, dp[i]);
    57         printf("%d
    ", ans);
    58         ms(dp, 0);
    59     }
    60     return 0;
    61 }
    View Code

     

  • 相关阅读:
    生成器
    迭代器
    装饰器
    闭包函数
    函数对象
    函数
    文件
    字符编码
    基本的数据类型和内置方法02
    基本的数据类型和内置方法01
  • 原文地址:https://www.cnblogs.com/denghaiquan/p/6680975.html
Copyright © 2020-2023  润新知