题目:两个人到一个有很多岛屿组成的国家,求两人按相同顺序参观的最大岛屿数。
分析:dp,LIS,LCS。本题有两种解决方案,LCS,LIS。
LCS:对两人分别排序,找出编号的 LCS即可 T = O(n^2);
LIS:利用映射关系,将 LCS转化成 LIS即可 T = O(nlogn);
转化有点恶心,求出排序后的 与a对应的的编号相同的 b点的位置 。
说明:写了一个 LIS的函数。。。不过和大黄的差了好多啊。。。ym~~。(2011-9-26 00:56)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct node
{
int id;
int in;
}visit;
visit a[ 1001 ];
visit b[ 1001 ];
int s[ 1001 ];
int v[ 1001 ];
int cmp( const void* a, const void* b )
{
visit *p = (visit *)a;
visit *q = (visit *)b;
if ( p->in == q-> in )
return p->id - q->id;
else return p->in - q->in;
}
int MUQ[ 1001 ];
int LIS( int n, int* Q )
{
int l,r,m,i,tail = 0;
for ( MUQ[ ++ tail ] = Q[ 1 ],i = 2 ; i <= n ; ++ i ) {
if ( MUQ[ tail ] < Q[ i ] ) {
MUQ[ ++ tail ] = Q[ i ];
continue;
}
for ( m=((r=tail)+(l=1)>>1) ; l < r ; m=(l+r)>>1 )
if ( MUQ[ m ] < Q[ i ] ) l = m+1;
else r = m;
MUQ[ m ] = Q[ i ];
}
return tail;
}
int main()
{
int n;
while ( scanf("%d",&n) != EOF && n ) {
for ( int i = 1 ; i <= n ; ++ i )
scanf("%d",&a[ i ].in);
for ( int i = 1 ; i <= n ; ++ i )
scanf("%d",&b[ i ].in);
for ( int i = 1 ; i <= n ; ++ i )
a[ i ].id = b[ i ].id = i;
qsort( &a[ 1 ], n, sizeof( visit ), cmp );
qsort( &b[ 1 ], n, sizeof( visit ), cmp );
for ( int i = 1 ; i <= n ; ++ i ) s[ a[ i ].id ] = i;
for ( int i = 1 ; i <= n ; ++ i ) v[ i ] = s[ b[ i ].id ];
printf("%d\n",LIS( n, v ));
}
return 0;
}