很水的一题
输入串a与串b;
Dp[i][j]表示a串中1~i与b串中1~j的子串的最长公共子序列。
Max{dp[i-1][j], dp[i][j-1]} (a[i]!=b[j])
Dp[i][j]= Dp[i-1][j-1]+1 (a[i]==b[j])
最后,a,b的最长公共子序列为dp[strlen(a)][strlen(b)]
但是我居然细节出错了尼玛。。
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; int max3(int a,int b,int c){ int d=b>c?b:c; return a>d?a:d; } int max2(int a,int b){ return a>b?a:b; } int dp[1001][1001]; int main(){ char a[1001],b[1001]; while(cin>>a>>b){ int lena=strlen(a); int lenb=strlen(b); memset(dp,0,sizeof(dp)); int i,j; if(a[0]==b[0])dp[0][0]=1; for(i=1;i<lena;i++) { // dp[i][0]+=dp[i-1][0]; if(a[i]==b[0])dp[i][0]++; else dp[i][0]=dp[i-1][0]; //忘了这边也要判断一下,晕 } for(i=1;i<lenb;i++) { // dp[0][i]+=dp[0][i-1]; if(a[0]==b[i])dp[0][i]++; else dp[0][i]=dp[0][i-1]; } for(i=1;i<lena;i++) for(j=1;j<lenb;j++){ //dp[i][j]+=max2(dp[i-1][j],dp[i][j-1]); if(a[i]==b[j])dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max2(dp[i][j-1],dp[i-1][j]); } cout<<dp[lena-1][lenb-1]<<endl; } return 0; }
当然 这个是从0开始的所以需要特判,,
如果输入从1开始就然后[0]赋值0就好了,不需要特判
#include<iostream> #include<string.h> #include<stdio.h> using namespace std; char a[1000]; char b[1000]; int dp[1000][1000]; //dp[i][j] is a[1~i] and b[1~j]'s common string's longest lenth int main(){ while(scanf("%s",a+1)!=EOF){ //cin one of the string scanf("%s",b+1); //cin the other int lena=strlen(a+1); int lenb=strlen(b+1); for(int i=0;i<=lena;i++){ dp[i][0]=0; } for(int j=0;j<=lenb;j++){ dp[0][j]=0; } for(int i=1;i<=lena;i++){ for(int j=1;j<=lenb;j++){ if(a[i]==b[j]){ 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 ",dp[lena][lenb]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。