首页 > 代码库 > UVa 10635 (LIS+二分) Prince and Princess
UVa 10635 (LIS+二分) Prince and Princess
题目的本意是求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 LOCAL14 freopen("10635in.txt", "r", stdin);15 #endif16 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]的LIS37 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 else48 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 }
大白书里面用到了lower_bound函数
函数介绍
lower_bound()返回一个 iterator 它指向在[first,last)标记的有序序列中可以插入value,而不会破坏容器顺序的第一个位置,而这个位置标记了一个大于value 的值。
效果是一样的
1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 8 const int INF = 1000000000; 9 const int maxn = 250 * 250;10 int num[maxn], s[maxn], g[maxn], d[maxn];11 12 int main(void)13 {14 #ifdef LOCAL15 freopen("10635in.txt", "r", stdin);16 #endif17 18 int T, kase;19 scanf("%d", &T);20 for(kase = 1; kase <= T; ++kase)21 {22 int N, p, q, x;23 scanf("%d%d%d", &N, &p, &q);24 memset(num, 0, sizeof(num));25 for(int i = 1; i <= p+1; ++i)26 {27 scanf("%d", &x);28 num[x] = i;29 }30 int n = 0;31 for(int i = 1; i <= q+1; ++i)32 {33 scanf("%d", &x);34 if(num[x])35 s[n++] = num[x];36 }37 //求s[1]...s[n]的LIS38 for(int i = 1; i <= n; ++i)39 g[i] = INF;40 int ans = 0;41 for(int i = 0; i < n; ++i)42 {43 int k = lower_bound(g+1, g+n+1, s[i]) - g;44 d[i] = k;45 g[k] = s[i];46 ans = max(ans, d[i]);47 }48 printf("Case %d: %d\n", kase, ans);49 }50 return 0;51 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。