• 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 }
  • 相关阅读:
    NoSQL学习1
    inno setup 软件打包
    cmapx 保存绘制好的图层
    qt之菜单栏的创建
    qt 软件打包
    可恶的 0xc0000005异常
    成长
    msChart组件安装与编程
    qt 工具下的dump工具导出文档出现异常解决方案
    qt 环境下mapx组件的鼠标跟踪
  • 原文地址:https://www.cnblogs.com/fzf123/p/2757716.html
Copyright © 2020-2023  润新知