[USACO17FEB] Why Did the Cow Cross the Road II P [树状数组优化dp]
题目描述见链接 .
设 表示 序列前 项, 序列前 项 的最大匹配数,
- 不相连:
- 相连:
经典的最长公共子序列算法 .
考虑优化, 发现 与 相连当且仅当 , 于是在 确定的情况下, 最多只有 个可能的取值,
所以可以记下 的位置 从小到大枚举 , 再枚举 种可能的 ,
从 转移过来, 使用 树状数组 优化 最大前缀 即可实现 .
#include<bits/stdc++.h>
#define reg register
const int maxn = 100005;
int N;
int A[maxn];
int B[maxn];
int tmp[maxn];
int pos[maxn];
struct Bit_Tree{
int v[maxn], lim;
void Add(int k, int x){
while(k <= lim){
v[k] = std::max(v[k], x);
k += k&-k;
}
}
int Query(int k){
if(k <= 0) return 0;
int s = 0;
while(k){
s = std::max(s, v[k]);
k -= k&-k;
}
return s;
}
} bit_t;
int main(){
scanf("%d", &N);
for(reg int i = 1; i <= N; i ++) scanf("%d", &A[i]);
for(reg int j = 1; j <= N; j ++) scanf("%d", &B[j]), pos[B[j]] = j;
bit_t.lim = N;
for(reg int i = 1; i <= N; i ++){
int dlim = std::max(1, A[i]-4), ulim = std::min(N, A[i]+4);
for(reg int j = dlim; j <= ulim; j ++) tmp[j] = bit_t.Query(pos[j]-1) + 1;
for(reg int j = dlim; j <= ulim; j ++) bit_t.Add(pos[j], tmp[j]);
}
printf("%d\n", bit_t.Query(N));
return 0;
}