P2102 LCIS
P2102\(\mathbf{} \begin{Bmatrix} \frac{{\Large SLOJ-P2102} }{{\color{Red}\Large Solution} }\mathbf{} {No.17} \end{Bmatrix}\times{}\) NeeDna
题意:求 \(a,b\) 两个串的最长公共上升子序列长度
(为CF10D简化版)
先思考朴素暴力,设 \(f_{i,j}\) 为在 \(a\) 中前 \(i\) 位,末尾为 \(b[ j ]\) 的答案。那么考虑转移,可以从 \(f_{i-1,j}\) 中直接转移,然后如果 \(a[i]=b[k],k \in[0,j-1]\) 那么可以转移 \(f_{i-1,k}+1\) 。这暴力就是 \(O(n^3)\) 的了。考虑优化,发现瓶颈在枚举 \(k\) 上,接着发现 \(f_{i-1,k}+1\) 在 \(j\) 增长的时候是单调不减的,所以用一个数保存一下即可,更新决策点当且仅当 \(a[i]>b[j]\),此时才可能保留单调性。
ac code:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10,M=5e3+10;
int n,a[N],b[N],f[M][M],ans;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
for(int i=1;i<=n;i++){
int maxv=1;
for(int j=1;j<=n;j++){
f[i][j]=f[i-1][j];
if(a[i]==b[j]) f[i][j]=max(f[i][j],maxv);
if(b[j]<a[i]) maxv=max(maxv,f[i-1][j]+1);
}
}for(int i=1;i<=n;i++) ans=max(ans,f[n][i]);
cout<<ans;
return 0;
}

浙公网安备 33010602011771号