UVa 10533.Prince and Princess

11788 ワード

テーマ接続:http://uva.onlinejudge.org/index.php?option=com_オンラインjudge&Itemid=8&page=show_problem&problem=1576
13935381
10635
Prince and Princess
Acceepted
C++
0.095
2014-07-24 03:41:18
 
 
Prince and PrincessInput:Standard Input
Output:Standard Output
Time Limit:3 Seconds
 
In a n n x n checsboard,Prince and Princess plys a game.The squares in the checssboard ard 1,2,3…n,as shown below:
 
Prince stands in square 1、make p jumps and finally reach square n.Henters a squarararar a squarare a a at most onece.So if we use xp to denote thep-th square henters、then x 1、x 1、x 2、…p+1 arararararap+1.eeededededededededededededededeaaaaaaaaaaaax+1.eeeeeeex+1.aaaaaaax+1.aaaaaaaaaaaaaaaaaaaaaaaax+1=the the the jumps and finally reach square n*n.We use y 1,y 2,…yq+1 to denote the sequence,and all q+1 numbers are different.
 
Figure 2 belows show a 3 x 3 square、a possible route for Prince and a different route for Princess.
 
The Prince moves along the sequence:1-->7-->4-->8-->3-->9(Black arrows)、while the Princess moves along sequence:1-->4-->3-->5-->2-->8-->9(White arrow.
The King--their father,has just come.“Why move separately?You are broother and sister!”said the King,“Ignore some jums and make sure that you’always together.”
 
For example,if the Prince ignores his 2 nd,3 rd,6 th jump,he'll follw the route:1->4--8->9.If the Princess Irereshher 3 rd,4 th,5 th,6 th jummp,she'll followthe same routute e-fime rotototototototomoute--The 2010 2010 2010 2010 2010 2010 2010-proutute e e e-4--Themomomonte-4.--The e 4--The e e e e e e 4.'The EEEEEgggggggggggggggggggggggggggggg wants to know the longest route they can move together、could you tell him?
 
Input 
The first line of the input contains a single integer t(1==t<=10)、the number of test cases followed.For each case、the first line contains three integers n、p、q(2==n=250、1=the innte+1)the sequence of the Prince.The third line contains q+1 different integers in the range[1.n*n],the sequence of the Princess.
 
Output 
For each test case,print the case number and the length of longest route.Look at the output for sample input for details.
 
Sample Input         Output for Sample Input
1 3 6 7 1 7 5 4 4 9 1 4 5 6 6 2 9
Case 1:4
 
問題の構想を解きます:学校でひざまずく試合のLCS nlognアルゴリズムのため、帰ってきて悪辣です。わざわざ同じ意味のテーマを探しました。この問題のように、簡単なLCSタイプですが、10^5ぐらいのデータ量は、スクロールdpを開くと、複雑度O(n^2)がタイムアウトします。したがって、LCS問題を下付きのLIS問題に転化して、LISのnlognアルゴリズムを使って、具体的な思想はインクリメントシーケンスを維持し、2分は上界を探し、要素を交換すればいいです。(DIM神に感謝します。このアルゴリズムを説明してください。)これで十分です。しかし、この問題と関係がないというと、データの範囲が大きすぎると、例えば64ビットレベルの数字になると、離散化を使って複雑度を下げることができます。yeah pengソースを拝む。
 
 
 1 #include <iostream>

 2 #include <cstring>

 3 #include <cstdio>

 4 #include <cstdlib>

 5 #include <cctype>

 6 #include <algorithm>

 7 #include <numeric>

 8 #include <map>

 9 #include <vector>

10 using namespace std;

11 

12 const int N = 250 * 250;

13 map<int, int> check;

14 vector<int> Stack;

15 

16 int main () {

17     int T, n, p, q, cur = 0;

18     int s1[N], s2[N];

19     scanf("%d", &T);

20     while (T --) {

21         Stack.clear();

22         check.clear();

23         scanf("%d%d%d", &n, &p, &q);

24         for (int i = 0; i <= p; ++ i) {

25             scanf("%d", &s1[i]);

26             check[s1[i] ] = i + 1;

27         }

28 

29         map<int, int> :: iterator it;

30 

31         for (int i = 0; i <= q; ++ i) {

32             scanf("%d", &s2[i]);

33             if (check.find(s2[i]) != check.end()) {

34                 s2[i] = check[s2[i]];

35             } else {

36                 s2[i] = 0;

37             }

38         }

39         /*

40         for (int i = 0 ; i <= p; ++ i) {

41             cout << check[s1[i] ] << " ";

42         }

43         cout << endl;

44         *//*

45         for (int i = 0 ; i <= q; ++ i) {

46             cout << s2[i] << " ";

47         }

48         cout << endl;

49 */

50         for (int i = 0; i <= q; ++ i) {

51             if (Stack.empty() || s2[i] > Stack[Stack.size() - 1]) {

52                 Stack.push_back(s2[i]);

53             } else {

54                 vector<int> :: iterator it = lower_bound(Stack.begin(), Stack.end(), s2[i]);

55                 *it = s2[i];

56             }

57         }

58         /*for (int i =  0; i < Stack.size(); ++ i ) {

59             cout << Stack[i] << " ";

60         }

61         cout << endl;*/

62         printf("Case %d: ", ++ cur);

63         cout << Stack.size() << endl;

64 

65     }

66     return 0;

67 }