首页 > 代码库 > zoj 2254 - Island Country

zoj 2254 - Island Country

题目:两个人到一个有很多岛屿组成的国家,求两人按相同顺序参观的最大岛屿数。

分析:dp,LIS,LCS。本题有两种解决方案,LCS,LIS。

           LCS:对两人分别排序,找出编号的 LCS即可 T = O(n^2);

           LIS:利用映射关系,将 LCS转化成 LIS即可 T = O(nlogn);

           转化有点恶心,求出排序后的 与a对应的的编号相同的 b点的位置 。

说明:写了一个 LIS的函数。。。不过和大黄的差了好多啊。。。ym~~。

#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;
}

zoj 2254 - Island Country