题目的本意是求LCS,但由于每个序列的元素各不相同,所以将A序列重新编号{1,2,,,p+1},将B序列重新编号,分别为B中的元素在A中对应出现的位置(没有的话就是0)。

在样例中就是A = {1 7 5 4 8 3 9},B = {1 4 3 5 6 2 8 9}

重新编号以后:

A = {1 2 3 4 5 6 7}, B = {1 4 6 3 0 0 5 7}(里面的0在求LIS时可以忽略)

这样求A、B的LCS就转变为求B的LIS

求LIS用二分优化,时间复杂度为O(nlogn)

第一次做的用二分求LIS的题是HDU 1025

http://www.cnblogs.com/AOQNRMGYXLMV/p/3862139.html

在这里再复习一遍

 1 //#define LOCAL
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 
 8 const int maxn = 250 * 250;
 9 int num[maxn], s[maxn], dp[maxn];
10 
11 int main(void)
12 {
13     #ifdef LOCAL
14         freopen("10635in.txt", "r", stdin);
15     #endif
16 
17     int T, kase;
18     scanf("%d", &T);
19     for(kase = 1; kase <= T; ++kase)
20     {
21         int N, p, q, x;
22         scanf("%d%d%d", &N, &p, &q);
23         memset(num, 0, sizeof(num));
24         for(int i = 1; i <= p+1; ++i)
25         {
26             scanf("%d", &x);
27             num[x] = i;
28         }
29         int n = 1;
30         for(int i = 1; i <= q+1; ++i)
31         {
32             scanf("%d", &x);
33             if(num[x])
34                 s[n++] = num[x];
35         }
36         //求s[1]...s[n]的LIS
37         dp[1] = s[1];
38         int len = 1;
39         for(int i = 2; i <= n; ++i)
40         {
41             int left = 1, right = len;
42             while(left <= right)
43             {
44                 int mid = (left + right) / 2;
45                 if(dp[mid] < s[i])
46                     left = mid + 1;
47                 else
48                     right = mid - 1;
49             }
50             dp[left] = s[i];
51             if(left > len)
52                 ++len;
53         }
54 
55         printf("Case %d: %d\n", kase, len);
56     }
57     return 0;
58 }
代码君

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2021-07-31
  • 2022-12-23
  • 2022-12-23
  • 2021-08-04
  • 2021-12-28
  • 2021-09-05
猜你喜欢
  • 2021-07-14
  • 2022-02-22
  • 2021-12-29
  • 2021-09-04
  • 2021-12-12
相关资源
相似解决方案