UVa -- 10635 Prince and Princess 【想法】

来源:互联网 发布:misumi软件 编辑:程序博客网 时间:2024/06/15 07:24

传送门
//给出两个序列, 求这两个序列的LCS.每个单序列保证两两不同. 由于数据量比较小, 那么直接n^2是可以过的. 但是如果数据量变大, 如1e4, 则n^2是肯定过不了的. 所以我们需要找出更优的算法.
//我们可以注意带每一个序列中的数是两两不同的, (以样例来说)我们对第一个序列重新编号(1,2,3,4,5,6,7), 那么对应第二个序列变成(1,4,6,3,0,0,5,7),0表示没有出现过在第一个序列中的数, 我们可以直接删除. 那么问题就转化为了求新的第二个序列的LIS,( 为什么可以这样, 好好想一想, 还是比较好想的!!! ) 复杂度变为nlogn, 对于数据量大一点的也是可以的.
AC Code

/** @Cain*/const int maxn=1e5+5;int cas = 1;int n,p,q;int num[maxn],g[maxn];int pp[maxn],qq[maxn];//num为所给数字串. g[i]表示d值为i的最小状态编号.(不存在就为inf)//g[i]最小都是1.int LIS(){    Fill(g,inf);    int maxlen = 0;    for(int i=1;i<=q+1;i++){        int pos = lower_bound(g+1,g+2+q,num[i]) - g;//所以都是从1开始.        g[pos] = num[i];        maxlen = max(maxlen,pos);    }    return maxlen;}void solve(){    scanf("%d%d%d",&n,&p,&q);    map<int,int>mp;    for(int i=0;i<=p;i++){        scanf("%d",&pp[i]);        mp[pp[i]] = i+1;    }    for(int i=0;i<=q;i++) scanf("%d",&qq[i]);    for(int i=0;i<=q;i++){        if(!mp[qq[i]]) num[i+1] = 0;        else num[i+1] = mp[qq[i]];    }    printf("Case %d: ", cas++);    printf("%d\n",LIS());}
原创粉丝点击