题意:经典DP题,几乎在任何算法书上都看到过。 一直不理解,今天顿悟??
对于长度为n和m的字符串中,要求最长公共子序列(LCS)可以不连续,但要保持顺序不变。 那么开二维数组dp,写出如下的状态转移方程。起始条件我们需要知道所有的dp[0][0~m]=dp[0~n][0]=0;那么根据以下递推式就可以推出来。 从最优子解角度去考虑,求dp[n][m]过程中,每一个dp[i][j]都是最大值,满足最优子解的要求。从无后效性的角度考虑,我怎么得到最大的dp对后面无影响,对比的只是i,j变大过程中s1[i]和s2[j]的关系,前面如何得到当前的DP,对后面的 DP 值 没有影响。
#include <iosream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MAXN 10005
using namespace std;
char s1[MAXN],s2[MAXN];
int dp[MAXN][MAXN];
int main(void)
{
while((scanf("%s%s",s1+1,s2+1))==2)
{
int n=strlen(s1+1);
int m=strlen(s2+1);
//printf("%d-%d",len1,len2);
for(int i=1; i<=m; i++)
{
dp[1][i]=0;
}
for(int i=1; i<=m; i++)
{
dp[i][1]=0;
}
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
if(s1[i]==s2[j])dp[i][j]=dp[i-1][j-1]+1;
else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
/*for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
printf("i=%d,j=%d,dp[i][j]=%d\n",i,j,dp[i][j]);
}
}*/
printf("%d\n",dp[n][m]);
}
}