DP思想,LIS(公共子序列的最大长度)。dp[i][j]表示序列a的前i项和序列b的前j项(不包括a[i][j]项)的最大子序列的长度。举个栗子:
A序列:a c d b d
B序列:b c a d b
i=1:dp[1][1]=0,dp[1][2]=0,dp[1][3]=1,dp[1][4]=1,dp[1][5]=1;
i=2:dp[2][1]=0,dp[2][2]=1,dp[2][3]=1,dp[2][4]=1,dp[2][5]=1;
i=3:dp[3][1]=0,dp[3][2]=1,dp[3][3]=1,dp[3][4]=2,dp[1][5]=2;
i=4:dp[4][1]=1,dp[4][2]=1,dp[4][3]=1,dp[4][4]=2,dp[4][5]=3;
i=5:dp[5][1]=1,dp[5][2]=1,dp[5][3]=1,dp[5][4]=2,dp[5][5]=3;
这个过程类似于找朋友,两个序列的每一项都要比一比!!
于是可以得出状态转移方程:
如果a[i-1] == b[j-1],dp[i][j] = dp[i-1][j-1] + 1;
如果a[i-1] != b[j-1],dp[i][j] = max(dp[i-1][j],dp[i][j-1])
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char a[1005],b[1005];
int dp[1005][1005];
int main(){
int la,lb;
while(~scanf("%s%s",&a,&b)){
la=strlen(a);
lb=strlen(b);
memset(dp,0,sizeof(dp));
for(int i=1;i<=la;i++){//从1开始防止数组越界
for(int j=1;j<=lb;j++){
if(a[i-1]==b[j-1])
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
printf("%d\n",dp[la][lb]);
}
return 0;
}
1530

被折叠的 条评论
为什么被折叠?



