LCS打印路径

第三遍做这道题,对DP有了更深的理解。动态规划是一种解决问题的方法、途径,最优化原理(principle of optimality),把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解。

说明:动态规划要求其子问题既要独立又要重叠,这初看上去貌似存在矛盾,其实不然。只是这里说的是两个不同的

概念。独立指的是同一问题的两个子问题不共享资源。而重叠子问题指的是子问题可以作为不同的问题的子问题出

现。

设X = <x1,x2...xm>, Y = <y1,y2...yn>为两个序列,并设Z = <z1,z2...zk>为X和Y的任意一个LCS。可以得出:

1、如果xm = yn,那么zk = xm = yn而且Z(k-1)是X(m-1)和Y(n-1)的一个LCS;

2、如果xm != yn,那么zk != xm蕴含Z是X(m-1)和Y的一个LCS;

3、如果xm != yn,那么zk != yn蕴含Z是X和Y(n-1)的一个LCS。

注:上面的Z(k-1)表示序列Z<z1,z2...zn>,其中n=k-1。其它的X()和Y()也是一样的。

很容易证明上述三点是成立的,详细证明见算法导论。所以LCS具有最优子结构。从上面也可以看出LCS问题中的重

叠子问题的性质。所以我们可以用动态规划来解决LCS问题。由LCS问题的最优子结构可得出递归式:

 

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=1000+10;
int dp[maxn][maxn];
char a[maxn],b[maxn];
int la,lb;
int main(){
    cin>>a>>b;
    la=strlen(a);
    lb=strlen(b);
    memset(dp,0,sizeof(dp));
    for(int i=1;i<=la;i++)
    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]);
    }
    int len=dp[la][lb];
    stack<char>ans;
    int i=la,j=lb;
    while(dp[i][j]){
        if(dp[i][j]==dp[i-1][j])    i--;
        else if(dp[i][j]==dp[i][j-1])    j--;
        else {
            ans.push(a[i-1]);
            i--;j--;
        }
    }
    while(!ans.empty()){
        printf("%c",ans.top());
        ans.pop();
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/depth/p/5781919.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值