这道题耗了我半天时间去弄明白,很不容易啊,不过收获还是很大,这是我接触动态规划的第二道题,第一道是那个数字三角形,那个很简单直接就理解了,动态转化方程也很容易写出来,这道题动态转化方程让我想了好长时间才理解,下面就是方程的理解
假设用数组a,b分别存放两个字符串
我用dp[i][j]表示a数组的第i项之前的子串和b数组第j项之前的字串的最长公共子序列,dp[][]初始化为零,
当a[i]=b[j],就说明dp[i][j]比前一项多了一个公共的,所以d[i][j]=d[i-1][j-1];
当两个不相等时,则说明d[i][j]与前面的最长公共子序列相等,分为两种,一种是dp[i][j-i],一种是dp[i-1][j],解释清楚些就是,a的第i-1项和b的第j项之前的公共字串或者a的第i项和b的第j-1项之前的公共字串,选择两个中最大的,画图最好理解了
下面就简单了,直接根据方程写就行了
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char a[300],b[300];
int dp[300][300];
int len1,len2,i,j;
while(scanf("%s%s",a,b)!=EOF)
{
memset(dp,0,sizeof(dp));
len1=strlen(a);
len2=strlen(b);
for(i=1;i<=len1;i++)
for(j=1;j<=len2;j++)
{
if(a[i-1]==b[j-1])
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=dp[i-1][j]>dp[i][j-1] ? dp[i-1][j] : dp[i][j-1];
}
printf("%d\n",dp[len1][len2]);
}
return 0;
}
数组在这道题开大些就可以AC了,继续向动态规划迈进,加油!!!