码迷,mamicode.com
首页 > 其他好文 > 详细

最长公共子序列 DP

时间:2015-04-26 10:54:56      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:

算法老师的作业,一道dp基础题,给你两个序列,问你最长公共子序列是什么,比如:(a,b)是(a,c,d,b)的子序列。注意不是最长公共子串,这里的子序列可以不连续。

两个for循环就出来了,每一个dp[i][j]可以从dp[i-1][j-1]、dp[i-1][j]、dp[i][j-1]三种情况更新过来,取个最大的,然后把路径用123存下来,最后再顺着路径找然后逆序输出就行。

sample input:

7 4
A B C B D A B
B C D B
7 6
A B C B D A B
B D C A B A
8 4
A B C D E F G H
D C B A

技术分享

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <stack>
using namespace std;
typedef long long LL;
const int INF=0x7fffffff;
const int MAX_N=1009;

char X[MAX_N],Y[MAX_N];
int m,n,ct;
int dp[MAX_N][MAX_N];
int b[MAX_N][MAX_N];
char ans[MAX_N];

void solve(){
    for(int i=1;i<=m;i++){
        for(int j=1;j<=n;j++){
            if(X[i]==Y[j]){
                dp[i][j]=dp[i-1][j-1]+1;
                b[i][j]=1;
            }
            else if(dp[i-1][j]>=dp[i][j-1]){
                dp[i][j]=dp[i-1][j];
                b[i][j]=2;
            }
            else{
                dp[i][j]=dp[i][j-1];
                b[i][j]=3;
            }
        }
    }
}

void go_back(int x,int y){
    if(x==0||y==0)return;
    if(b[x][y]==1){
        ans[++ct]=X[x];
        return go_back(x-1,y-1);
    }
    if(b[x][y]==2){
        return go_back(x-1,y);
    }
    if(b[x][y]==3){
        return go_back(x,y-1);
    }
}

int main(){
    printf("输入x和y的长度:\n");
    while(scanf("%d%d",&m,&n)!=EOF){
        memset(dp,0,sizeof(dp));
        memset(b,0,sizeof(b));
        printf("输入序列X:\n");
        for(int i=1;i<=m;i++){
            scanf(" %c",&X[i]);
        }
//        getchar();
        printf("输入序列Y:\n");
        for(int i=1;i<=n;i++){
            scanf(" %c",&Y[i]);
        }
        solve();
        printf("最长子序列长度为:%d\n",dp[m][n]);

        ct=0;
        go_back(m,n);
        printf("最长子序列之一为:\n");
        for(int i=ct;i>=1;i--){
            printf("%c ",ans[i]);
        }

        printf("\n\n输入x和y的长度:\n");
    }
    return 0;
}


最长公共子序列 DP

标签:

原文地址:http://blog.csdn.net/qdbszsj/article/details/45286347

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!