LCS+记录路径

https://blog.csdn.net/someone_and_anyone/article/details/81044153

当串1 和 串2 的位置i和位置j匹配成功时,

dp[i][j]=dp[i-1][j-1]+1,也就是说此状态由状态dp[i-1][j-1]转移而来,用数组记录为1,

当匹配不成功时,dp[i-1][j]和dp[i][j-1]去一个最大的,用数组分别记为2和3.

根据记录数组寻找路径:

当记录数组为1时,说明次时的i和j想等,并且此状态由i-1和j-1转移而来,所以i=i-1,j=j-1

当记录数组为2时,说明此时i和j对应的数符不等,并且此状态由j-1转移而来,所以直接j--;

当记录数组为2时,说明此时i和j对应的数符不等,并且此状态由i-1转移而来,所以直接i--;

例题:

#include<bits/stdc++.h>
using namespace std;
const int N=1000+7;
int dp[N][N];
int mark[N][N];
char s1[N],s2[N];
int main()
{
    cin>>s1+1>>s2+1;
    int n=strlen(s1+1);
    int m=strlen(s2+1);
    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;
                mark[i][j]=1;
            }
            else if(dp[i][j-1]>dp[i-1][j]){
                dp[i][j]=dp[i][j-1];
                mark[i][j]=2;    
            }
            else {
                dp[i][j]=dp[i-1][j];
                mark[i][j]=3;
            }
         }
    string ans="";
    int i=m,j=n;
    while(i>0&&j>0){
        if(mark[i][j]==1) {
            ans+=s1[i];
            i--;j--;
        }
        else if(mark[i][j]==2) {
            j--;
        }
        else i--;
    }
    reverse(ans.begin(),ans.end());
    cout<<ans<<endl;
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Accepting/p/12457402.html
LCS