您的位置:首页 > 其它

洛谷 排列LCS P1439 (LCS)

2017-07-27 09:38 274 查看
看到黑书上写着,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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: