您的位置:首页 > 其它

UVA 10635 Prince and Princess(LIS)

2012-11-06 20:47 399 查看
又是训练指南上的一道经典题~~

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

/*
Author:Zhaofa Fang
Lang:C++
*/
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <iostream>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <string>
#include <utility>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;

typedef long long ll;
#define DEBUG(x) cout<< #x << ':' << x << endl
#define REP(i,n) for(int i=0;i < (n);i++)
#define FOR(i,s,t) for(int i = (s);i <= (t);i++)
#define PII pair<int,int>
#define PB push_back
#define MP make_pair
#define FI first
#define SE second
#define lowbit(x) (x&(-x))
#define INF (1<<30)

const int maxn = 250*250+10;
int A[maxn],B[maxn],pos[maxn],dp[maxn];

int LIS(int n)
{
for(int i=1;i<=n;i++)A[i] = INF,dp[i] = 0;
for(int i=0;i<n;i++)
{
int k = lower_bound(A+1,A+1+n,B[i]) - A;
A[k] = B[i];
dp[i] = k;
}
int mx = -1;
REP(i,n)mx = max(dp[i],mx);
return mx;
}
int main()
{
//freopen("in","r",stdin);
int T;
scanf("%d",&T);
REP(cas,T)
{
printf("Case %d: ",cas+1);
int n,p,q;
scanf("%d%d%d",&n,&p,&q);
memset(pos,0,sizeof(pos));
REP(i,p+1)
{
scanf("%d",&A[i]);
pos[A[i]] = i+1;
}
REP(i,q+1)
{
scanf("%d",&B[i]);
B[i] = pos[B[i]];
}
printf("%d\n",LIS(q+1));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: