首页 > 代码库 > 最长上升子序列(LIS)题目合集

最长上升子序列(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\n", 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\n", 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\n", 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("\n");
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:\n",t++);
46         printf("  maximum possible interceptions: %d\n", 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("*\n");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\n", ans);
58         ms(dp, 0);
59     }
60     return 0;
61 }
View Code

 

 

 

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