Laoj P1659 noip模拟 - 道路规划(LCS的nlogn算法)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Laoj P1659 noip模拟 - 道路规划(LCS的nlogn算法)相关的知识,希望对你有一定的参考价值。
试题描述
|
输入格式
|
第一行,一个整数,n。
第二行,n个整数,第i个数表示北部第i个城市的编号。 第三行,n个整数,第i个数表示南部第i个城市的编号。 |
输出格式
|
输出合法的城市集合的最大大小。
|
输入示例
|
5
1 4 5 2 3 3 4 2 1 5 |
输出示例
|
3
|
注释说明
|
【样例解释】
{1,3,4},{1,2,3}和{2,3,5}都是合法的方案,大小是3,显然是最大值。 【数据规模】 对于20%数据,n<=50; 对于50%数据,n<=500; 对于70%数据,n<=5000; 对于100%数据,n<=10^5。 |
【分析】
一开始的想法是先预处理然后求个lis之类的,也算靠了点边。
后来发现把第二个序列翻转后,取二者的lcs即可,数据范围10^5,明显留给nlogn的。
LCS的nlogn算法其实就是把LCS转成LIS,LIS的nlogn算法想必大家都会了。
怎么转化呢,举个栗子:
比如样例数据是1 4 5 2 3和3 4 2 1 5,第二个序列翻转后为5 1 2 4 3,用c[i]来表示第一个序列的第i个数在第二个序列中的位置。
此时c[5]={4, 2, 5, 3, 1},现在再对c数组求LIS就可以了。
注意,要求是集合中任意两个城市都为“平等互惠”,如果我们求出来LCS=1的话,这个集合就为空。
【代码】
1 #include <bits/stdc++.h> 2 #define inf 0x7fffffff 3 using namespace std; 4 5 int n, a[100005], b[100005], c[100005], x, g[100005], ans, k, f[100005]; 6 7 void init() { 8 cin >> n; 9 for (int i=1;i<=n;++i) 10 scanf("%d", &a[i]); 11 for (int i=n;i>0;--i) { 12 scanf("%d", &x); 13 b[x]=i; 14 } 15 for (int i=1;i<=n;++i) 16 c[i]=b[a[i]]; 17 } 18 19 void lis() { 20 for (int i=1;i<=n;++i) 21 g[i]=inf; 22 for (int i=1;i<=n;++i) { 23 k=lower_bound(g+1, g+n+1, c[i])-g; 24 g[k]=c[i]; 25 f[i]=k; 26 ans=max(ans, f[i]); 27 } 28 } 29 30 int main() { 31 init(); 32 lis(); 33 if (ans!=1) 34 cout << ans << endl; 35 else 36 cout << 0 << endl; 37 }
以上是关于Laoj P1659 noip模拟 - 道路规划(LCS的nlogn算法)的主要内容,如果未能解决你的问题,请参考以下文章