UVA 10635 Prince and Princess(LIS)

又是训练指南上的一道经典题~~  

http://uva.onlinejudge.org/external/106/10635.html

题意:有两个长度分别为p+1和q+1的序列,每个序列各个元素互不相同,且都是1~n^2的整数。求俩序列的LCS。

分析:LCS的O(pq)复杂度显然太慢。注意到“每个序列各个元素互不相同,且都是1~n^2的整数”,所以有个巧妙的转换,把A中的元素重新

按1~p+1编号,同时B也相同的映射编号,由于A为递增序列,所以LCS就是B中最长递增子序列,即LIS.这样就转换成求B的LIS问题,可以

在O(nlogn)的时间内解决。

LIS:

设dp[i]为以A[i]结尾的最长上升子序列的长度。

O(n^2)解法:dp[i] = max{0,dp[j] | j < i , Aj < Ai} + 1;

O(nlogn)解法:假设已经两个状态a和b满足Aa<Ab且dp[a]=dp[b];那么后续所有状态i选择a并不会比b差。这样,对于相同的dp值,就只需保留A最小的一个(详见代码)。

View Code
 1 /*

 2 Author:Zhaofa Fang

 3 Lang:C++

 4 */

 5 #include <cstdio>

 6 #include <cstdlib>

 7 #include <sstream>

 8 #include <iostream>

 9 #include <cmath>

10 #include <cstring>

11 #include <algorithm>

12 #include <string>

13 #include <utility>

14 #include <vector>

15 #include <queue>

16 #include <stack>

17 #include <map>

18 #include <set>

19 using namespace std;

20 

21 typedef long long ll;

22 #define DEBUG(x) cout<< #x << ':' << x << endl

23 #define REP(i,n) for(int i=0;i < (n);i++)

24 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)

25 #define PII pair<int,int>

26 #define PB push_back

27 #define MP make_pair

28 #define FI first

29 #define SE second

30 #define lowbit(x) (x&(-x))

31 #define INF (1<<30)

32 

33 const int maxn = 250*250+10;

34 int A[maxn],B[maxn],pos[maxn],dp[maxn];

35 

36 int LIS(int n)

37 {

38     for(int i=1;i<=n;i++)A[i] = INF,dp[i] = 0;

39     for(int i=0;i<n;i++)

40     {

41         int k = lower_bound(A+1,A+1+n,B[i]) - A;

42         A[k] = B[i];

43         dp[i] = k;

44     }

45     int mx = -1;

46     REP(i,n)mx = max(dp[i],mx);

47     return mx;

48 }

49 int main()

50 {

51     //freopen("in","r",stdin);

52     int T;

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

54     REP(cas,T)

55     {

56         printf("Case %d: ",cas+1);

57         int n,p,q;

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

59         memset(pos,0,sizeof(pos));

60         REP(i,p+1)

61         {

62             scanf("%d",&A[i]);

63             pos[A[i]] = i+1;

64         }

65         REP(i,q+1)

66         {

67             scanf("%d",&B[i]);

68             B[i] = pos[B[i]];

69         }

70         printf("%d\n",LIS(q+1));

71     }

72     return 0;

73 }

你可能感兴趣的:(uva)