Title to face two sequences a, b are the length n, m find the longest common subsequence rising, seeking a bit Baidu problem common subsequence is called if the LCS, called the rise LCIS. Dp's are examples.
First is that the longest common subsequence, this is a more classic dp problem, we can easily write
1. Status F. [I] [j] represents a sequence matching the sequence b i-th to j-th matching the longest length
2. The state transition equation
F[i][j] = max(F[i-1][j] , F[i][j-1]) (a[i] != b[j])
F[i][j] = F[i-1][j-1]+1(a[i] = b[j])
The answer lies in F [n] [m] in
Code
#include<bits/stdc++.h>
using namespace std;
int n,m,f[5010][5010];
char a[5010],b[5010];
int main(){
scanf("%s",a+1);
scanf("%s",b+1);
n=strlen(a+1);
m=strlen(b+1);
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
f[i][j]=max(f[i-1][j],f[i][j-1]);
if(a[i]==b[j]) f[i][j]=f[i-1][j-1]+1;
}
}
printf("%d",f[n][m]);
return 0;
}
Then let us consider the longest common subsequence rise
1. Definitions Status: F [x] [y] indicates a matching string length x, b string matching length y, and with b [j] end of the sequence length.
2. The state transition equation:
F[i][j]=F[i][j] = F[i-1][j] (a[i] != b[j])
F[i][j] = max(F[i-1][k]+1) (1 <= k <= j-1 && b[j] > b[k])
For the first equation we will be understood that when a [i]! = A [j] we used sequence b to match a sequence of a failure to match the a [i] is the number does not contribute to this sequence, i.e., does not consider consider it does not matter
For the second equation we can understand when the b sequence of the j number of hits, we can select all transferred foregoing state, but to ensure b [j]> b [k]
#include<bits/stdc++.h>
using namespace std;
int n,m,ans,a[3010],b[3010],f[3010][3010];
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i<=m;++i) scanf("%d",&b[i]);
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
f[i][j]=f[i-1][j];
if(a[i]==b[j]){
int maxn=0;
for(int k=1;k<=j-1;++k){
if(b[j]>b[k]) maxn=max(maxn,f[i-1][k]);
}
f[i][j]=maxn+1;
}
}
}
for(int i=1;i<=m;++i) ans=max(ans,f[n][i]);
printf("%d",ans);
return 0;
}
However, such an approach may arrive in the worst case O (n ^ 3), we can consider optimization, we can see whether you can find the maximum value in the third optimize certain heavy cycle? We Discovery second transfer equation b [j]> b [k], when there is a sequence of a [i] = b [j] that is a [i]> b [k], we can use a maximum MAXN be able to save the value of each maximum, i.e. when a [i]> b [j] when it is updated, f [i] [j] = maxn + 1 when a [i] = b [j] when;
#include<bits/stdc++.h>
using namespace std;
int n,m,ans,a[3010],b[3010],f[3010][3010];
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i<=m;++i) scanf("%d",&b[i]);
for(int i=1;i<=n;++i){
int maxn=0;
for(int j=1;j<=m;++j){
f[i][j]=f[i-1][j];
if(a[i]>b[j]) maxn=max(maxn,f[i-1][j]);
if(a[i]==b[j]) f[i][j]=maxn+1;
}
}
for(int i=1;i<=m;++i) ans=max(ans,f[n][i]);
printf("%d",ans);
return 0;
}
We can still find f [i] [j] transfers only used the f [i] [j-1] number, we can then optimize! Optimize our use of space rolling array.
#include<bits/stdc++.h>
using namespace std;
int n,m,ans,a[3010],b[3010],f[3010];
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;++i) scanf("%d",&a[i]);
for(int i=1;i<=m;++i) scanf("%d",&b[i]);
for(int i=1;i<=n;++i){
int maxn=0;
for(int j=1;j<=m;++j){
if(a[i]>b[j]) maxn=max(maxn,f[j]);
if(a[i]==b[j]) f[j]=maxn+1;
}
}
for(int i=1;i<=m;++i) ans=max(ans,f[i]);
printf("%d",ans);
return 0;
}
End Sahua! !