您的位置:首页 > 其它

【SJTUOJ笔记】P1072 小X的生物实验

2018-02-14 11:29 204 查看
https://acm.sjtu.edu.cn/OnlineJudge/problem/1072

看完题目,第一感觉是:这不裸LCS吗,前面那些条件有什么用?再看数据范围,发现如果还用一般LCS的O(n2)O(n2)做法,肯定会超时。那么必须用到所给的条件:每个序列中,1..N1..N之间的每个数恰好出现5次。

回想一般LCS的转移方程。用f[i, j]f[i, j]表示两个串分别到位置ii和位置jj的LCS长度,那么有

f[i, j]={f[i−1, j−1]+1max{f[i−1, j],f[i, j−1]}(a[i]=b[j])(a[i]≠b[j])f[i, j]={f[i−1, j−1]+1(a[i]=b[j])max{f[i−1, j],f[i, j−1]}(a[i]≠b[j])

我们可以把1..N1..N每次出现的位置提前存储起来,这样,利用树状数组,就可以实现log(n)log⁡(n)级别的修改和求maxmax。

核心部分如下:

//已经用pos[i][j]存储了数字i第j次出现的位置

//find和change函数是正常的树状数组查找、修改函数

int ans = 0;

for (int i = 1; i <= n; ++i){

int x;

cin >> x; // 读入第二个字串

for (int j = 4; ~j; –j){

int t = find(pos[x][j] - 1) + 1;

ans = max(t, ans);

change(pos[x][j], t);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: