HDU 1159 Common Subsequence --- DP入门之最长公共子序列
基础的最长公共子序列
#include <bits/stdc++.h> using namespace std; const int maxn=1e3+5; char c[maxn],d[maxn]; int dp[maxn][maxn]; int main() { while(scanf("%s%s",c,d)!=EOF) { memset(dp,0,sizeof(dp)); int n=strlen(c); int m=strlen(d); for(int i=0;i<n;i++) for(int j=0;j<m;j++) if(c[i]==d[j]) dp[i+1][j+1]=dp[i][j]+1; else dp[i+1][j+1]=max(dp[i+1][j],dp[i][j+1]); printf("%d\n",dp[n][m]); } return 0; }
再附上一个既可以输出长度也可以输出字符串的代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=1e3+5; char s1[maxn],s2[maxn]; int b[maxn][maxn],dp[maxn][maxn]; void pr(int i,int j) { if(i==0||j==0) return ; if(b[i][j]==1) { pr(i-1,j-1); printf("%c",s1[i]); } else if(b[i][j]==2) pr(i-1,j); else pr(i,j-1); } int main() { while(scanf("%s%s",s1,s2)!=EOF) { memset(b,0,sizeof(b)); memset(dp,0,sizeof(dp)); int len1=strlen(s1),len2=strlen(s2); for(int i=len1;i>=1;i--) s1[i]=s1[i-1];//这里注意不要写成从前往后跑的 for(int i=len2;i>=1;i--) s2[i]=s2[i-1]; for(int i=1;i<=len1;i++) for(int j=1;j<=len2;j++) { if(s1[i]==s2[j]) { dp[i][j]=dp[i-1][j-1]+1; b[i][j]=1; } else if(dp[i-1][j]>dp[i][j-1]) { dp[i][j]=dp[i-1][j]; b[i][j]=2; } else { dp[i][j]=dp[i][j-1]; b[i][j]=3; } } //这个是长度 //printf("%d\n",dp[len1][len2]); //这个是LCS序列 pr(len1,len2); puts(""); } return 0; }