洛谷 排列LCS P1439 (LCS)

来源:互联网 发布:淘宝运费险如何使用 编辑:程序博客网 时间:2024/06/07 19:08

看到黑书上写着,LCS是稀疏匹配,只需要关注能让答案更新的地方就可以了。


也就是当a[i]==b[j],dp[i+1][j+1]=dp[i][j]+1.这种情况。


所以对于每一个i,我们只需要关心,和a[i]相等的值再b种的位置j,记为pair[i]。


所以i从0开始更新,去找出pair[j]小于pair[i]的最大的dp[j],这个过程用个线段树或者树状数组优化就好了。


其实就是转换成先找到a在b种对应位置,然后根据位置的值来求lis的一个问题了。


如果值不唯一的话,就将一个值对应的所有坐标逆序排布。

比如

a: 1 3 2

b: 3 2 2 1 3

就把a对应为 (4) (5 1) (2 3)

逆序是为了保证相同的值没有重复利用,一个a[i]只能匹配一个。



代码:

#include <bits/stdc++.h>#define lson o<<1#define rson o<<1|1#define MID int mid=(l+r)>>1;using namespace std;const int maxn=1e5+5;int bit[maxn];int book[maxn];int pos[maxn];int a[maxn];int n;int val[maxn<<2];void update(int o, int l, int r, int x, int y){    if(l==r)    {        val[o]=max(val[o], y);        return;    }    MID;    if(x>mid)update(rson, mid+1, r, x, y);    else update(lson, l, mid, x, y);    val[o]=max(val[lson], val[rson]);    return;}int query(int o, int l, int r, int x, int y){    if(x<=l && r<=y)    {        return val[o];    }    MID    int res=0;    if(x<=mid)res=query(lson, l, mid, x, y);    if(y>mid)res=max(res, query(rson, mid+1, r, x, y));    return res;}int main(){    int  i, j;    cin>>n;    for(i=1; i<=n; i++)    {        scanf("%d", &a[i]);        book[a[i]]=i;    }    for(i=1; i<=n; i++)    {        scanf("%d", &a[i]);        pos[book[a[i]]]=i;    }    int ans=1;    int ma=0;    update(1, 1, n, pos[1], 1);    for(i=2; i<=n; i++)    {        if(pos[i]-1>=1)ma=query(1, 1, n, 1, pos[i]-1);        else ma=0;        update(1, 1, n, pos[i], ma+1);        ans=max(ans, ma+1);    }    printf("%d\n", ans);}


原创粉丝点击