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 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 }

代码君

大白书里面用到了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 LOCAL
15         freopen("10635in.txt", "r", stdin);
16     #endif
17
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]的LIS
38         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 }

代码君

UVa 10635 (LIS+二分) Prince and Princess

时间: 2024-10-13 22:15:25

UVa 10635 (LIS+二分) Prince and Princess的相关文章

uva 10635 Prince and Princess(LCS问题转化成LIS问题O(nlogn))

题目大意:有两个长度分别为p+1和q+1的序列,每个序列中的各个元素互不相同,且都是1~n^2之间的整数.两个序列的第一个元素均为1.求出A和B的最长公共子序列长度. 分析:本题是LCS问题,但是p*q<=62500,O(pq)的算法显然会LE.在这里有一个条件,每个序列中的各个元素互不相同,所以可以把A中元素重新编号为1~p+1.例如,样例中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

UVA - 10635 - Prince and Princess (LCS转化为LIS)

题目传送:UVA - 10635 思路:直接思路是两个串的LCS,不过这个题可以转化为LIS,因为说了序列中各个元素互不相同,所以可以来个映射算出第二个字符串中的字符对应第一个字符串中字符的位置(不存在即删去),然后算出这些位置的LIS即可 AC代码: #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <cmath> #in

uva 10635 Prince and Princess(DP)

uva 10635 Prince and Princess(DP) In an n x n chessboard, Prince and Princess plays a game. The squares in the chessboard are numbered 1, 2, 3 ... n*n, as shown below: Prince stands in square 1, make p jumps and finally reach square n*n. He enters a

算法竞赛与入门经典---P66 [UVA 10635] Prince and Princess

Prince and PrincessInput: Standard Input Output: Standard Output Time Limit: 3 Seconds In an n x n chessboard, Prince and Princess plays a game. The squares in the chessboard are numbered 1, 2, 3 ... n*n, as shown below: Prince stands in square 1, ma

uva10635 Prince and Princess LCS 变 lIS

// uva10635 Prince and Princess LCS 变 lIS // 本意求LCS,但是规模有60000多,复杂度肯定不够 // 注意如果俩个序列的值的范围相同,那么可以在一个 // 串中记录在另外一个串中的位置.这样就可以转化成 // 最长上升子序列的问题啦,复杂度是nlogn,可以ac // 这题,还是挺有考究的价值的,很不错 // 哎,继续练吧..... #include <algorithm> #include <bitset> #include <

UVA10635 Prince and Princess(LIS)

题意:王子和公主同时从1出发走到 n*n, 求他们两个路径的最长公共子序列: 思路:因为这题n有250,如果用LCS负责度为O(n^2),容易超时,于是我们选择它的优化版Lis算法来求最长公共子序列,这样我们的复杂度就降为O(n*logn)了. Lis算法: 先回顾经典的O(n^2)的动态规划算法,设A[t]表示序列中的第t个数,F[t]表示从1到t这一段中以t结尾的最长上升子序列的长度,初始时设F[t] = 0(t = 1, 2, ..., len(A)).则有动态规划方程:F[t] = ma

强连通+二分匹配(hdu4685 Prince and Princess)

Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submission(s): 1267    Accepted Submission(s): 358 Problem Description There are n princes and m princesses. Princess can marry any prince. B

UVa10653.Prince and Princess

题目连接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1576 13935381 10635 Prince and Princess Accepted C++ 0.095 2014-07-24 03:41:18 Prince and PrincessInput: Standard Input Output: Standard Output

HDU 4685 Prince and Princess

Prince and Princess Time Limit: 3000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 468564-bit integer IO format: %I64d      Java class name: Main There are n princes and m princesses. Princess can marry any prince. But prin