这里搬过来老师的ppt
参考程序
#include <bits/stdc++.h>
using namespace std;
/*
x[1..m], y[1..n]
x[m]==y[n] the result is (x[1..m-1], y[1..n-1]) + 1
x[m]!=y[n] the max of the two (x[1..m-1], y[1..n]), (x[1..m],y[1..n-1])
*/
int c[10][10];
int lcs(char x[], int m, char y[], int n){
int t;
if(c[m][n]!=-1)
return c[m][n];
if(x[m-1]==y[n-1]){
t=lcs(x,m-1,y,n-1)+1;
c[m][n]=t;
return t;
}
int t1,t2;
t1=lcs(x,m,y,n-1);
t2=lcs(x,m-1,y,n);
t=t1>t2?t1:t2;
c[m][n]=t;
return t;
}
int main()
{
char x[]="ABCBDAB", y[]="BDCABA";
int i,j;
for(i=0;i<10;i++)
for(j=0;j<10;j++)
c[i][j]=-1;
for(i=0;i<10;i++) c[i][0]=0;
for(j=0;j<10;j++) c[0][j]=0;
cout<<lcs(x,strlen(x), y, strlen(y));
/*for(i=1;i<=strlen(x);i++){
for(j=1;j<=strlen(y);j++){
if(x[i]==y[j])
c[i][j]=c[i-1][j-1]+1;
else{
c[i][j]=c[i-1][j]>c[i][j-1]?c[i-1][j]:c[i][j-1];
}
}
}*/
//cout<<c[strlen(x)][strlen(y)];
return 0;
}
例题:
#include <bits/stdc++.h>
using namespace std;
int c[1001][1001];
char x[100010],y[100010];
int f(char x[], int m, char y[], int n) {
int t;
if(c[m][n]!=-1)
return c[m][n];
if(x[m-1]==y[n-1]) {
t=f(x,m-1,y,n-1)+1;
c[m][n]=t;
return t;
}
int t1,t2;
t1=f(x,m,y,n-1);
t2=f(x,m-1,y,n);
t=t1>t2?t1:t2;
c[m][n]=t;
return t;
}
int main() {
gets(x);
gets(y);
int len1=strlen(x);
int len2=strlen(y);
int i,j;
int len=max(len1,len2);
for(i=0; i<200; i++)
for(j=0; j<200; j++)
c[i][j]=-1;
for(i=0; i<200; i++) c[i][0]=0;
for(j=0; j<200; j++) c[0][j]=0;
cout<<f(x,strlen(x), y, strlen(y));
return 0;
}
另一个关于子序列的题,直接在这里补充了
比较简单的一种算法
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5;
int a[N],sum[N];//sum[i]记录以i结尾的最长上升子序列的和
int main() {
int n;
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int ans=0;
for(int i=1;i<=n;i++){
sum[i]=a[i];//最短时是他本身
for(int j=1;j<i;j++){
if(a[j]<a[i]&&sum[j]+a[i]>sum[i])
sum[i]=sum[j]+a[i];
}
ans=max(ans,sum[i]);
}
cout<<ans;
return 0;
}