• 动态规划-最长公共子序列与最长公共子串


    1.最长公共子序列

    参考博客:

    http://blog.csdn.net/hrn1216/article/details/51534607

    http://blog.csdn.net/u013074465/article/details/45392687

    代码:

    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 101
    #define MAX 1<<30
    #define V vector<int>
    
    using namespace std;
    
    int a[LEN],b[LEN]; 
    int dp[LEN][LEN];
    int N,M;
    vector<vector<int> > ans;
    
    void printDP(){
        int i,j;
        F(i,1,N+1){
            F(j,1,M+1){
                O("%d	",dp[i][j]);
            }
            OL("
    ");
        }
    }
    
    void buildLCS(int x,int y,V vec){
        while(x>0 && y>0){
            if(a[x]==b[y]){
                vec.push_back(a[x]);
                x--;y--;
            }else{
                if(dp[x-1][y]>dp[x][y-1]){
                    x--;
                }else if(dp[x-1][y]<dp[x][y-1]){
                    y--;
                }else{
                    buildLCS(x,y-1,vec);
                    x--;
                }
            }
        }
        int i=vec.size()-1;
        while(i>=0){
            O("%d ",vec[i]);
            i--;
        }
        OL("");
    }
    
    int main(){
        freopen("LCS.txt","r",stdin);
        int i,j;
        scanf("%d",&N);
        F(i,1,N+1) I("%d",&a[i]);
        scanf("%d",&M);
        F(i,1,M+1) I("%d",&b[i]);
        F(i,1,N+1){ 
            F(j,1,M+1){
                if(a[i]==b[j])
                    dp[i][j]=dp[i-1][j-1]+1;
                else
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            }
        }
        printDP();
        O("最长公共子序列长度: %d
    ",dp[N][M]);
        V vec;
        buildLCS(N,M,vec);
        return 0;
    }
    View Code

    测试数据:

    9
    3 5 7 4 8 6 7 8 2
    8
    1 3 4 5 6 7 7 8
    

    2.最长公共子串

    代码:

    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 101
    #define MAX 1<<30
    #define V vector<int>
    
    using namespace std;
    
    int a[LEN],b[LEN]; 
    int dp[LEN][LEN];
    int N,M;
    vector<vector<int> > ans;
    
    void printDP(){
        int i,j;
        F(i,1,N+1){
            F(j,1,M+1){
                O("%d	",dp[i][j]);
            }
            OL("
    ");
        }
    }
    
    int main(){
        freopen("最长公共子串.txt","r",stdin);
        int i,j;
        scanf("%d",&N);
        F(i,1,N+1) I("%d",&a[i]);
        scanf("%d",&M);
        F(i,1,M+1) I("%d",&b[i]);
        int mx,my,mlen=0;
        F(i,1,N+1){ 
            F(j,1,M+1){
                if(a[i]==b[j]){
                    dp[i][j]=dp[i-1][j-1]+1;
                    if(mlen<dp[i][j]){
                        mlen=dp[i][j];
                        mx=i;
                        my=j;
                    }
                }
                else
                    dp[i][j]=0;
            }
        }
        printDP();
        O("最长公共子序列长度: %d
    ",mlen);
        V ans;
        while(dp[mx][my]){
            ans.insert(ans.begin(),a[mx]);
            mx--;my--;
        }
        FF(i,ans.size()){
            printf("%d ",ans[i]);
        }
        return 0;
    }
    View Code

    测试数据:

    9
    3 5 7 4 8 6 7 8 2
    8
    1 3 4 8 6 7 7 8
    

    3.相似基因

    代码:

    #include <stdio.h>
    #include <memory.h>
    #include <math.h>
    #include <string>
    #include <vector>
    #include <set>
    #include <stack>
    #include <queue>
    #include <algorithm>
    #include <map>
    
    
    #define I scanf
    #define OL puts
    #define O printf
    #define F(a,b,c) for(a=b;a<c;a++)
    #define FF(a,b) for(a=0;a<b;a++)
    #define FG(a,b) for(a=b-1;a>=0;a--)
    #define LEN 110
    #define MAX 1<<30
    #define V vector<int>
    
    using namespace std;
    
    
    int dp[LEN][LEN];
    int mat[5][5]={
    {5,-1,-2,-1,-3},
    {-1,5,-3,-2,-4},
    {-2,-3,5,-2,-2},
    {-1,-2,-2,5,-1},
    {-3,-4,-2,-1,0}};
    
    int to(char ch){
        if(ch=='A') return 0;
        else if(ch=='C') return 1;
        else if(ch=='G') return 2;
        else if(ch=='T') return 3;
        else return 4;
    }
    
    int main(){
    //    freopen("相似基因.txt","r",stdin);
        int an,bn,i,j;
        char buf[LEN];
        string a,b;
        I("%d",&an);
        I("%s",buf);
        a=buf;
        a.insert(0,"#");
        I("%d",&bn);
        I("%s",buf);
        b=buf;
        b.insert(0,"#");
        memset(dp,-127,sizeof(dp));
        dp[0][0]=0;
        for(i=0;i<=an;i++){
            for(j=0;j<=bn;j++){
                if(i && j) dp[i][j]=max(dp[i][j],dp[i-1][j-1] + mat[to(a[i])][to(b[j])]  );
                if(i) dp[i][j]=max(dp[i][j],dp[i-1][j] + mat[to(a[i])][4]  );
                if(j) dp[i][j]=max(dp[i][j],dp[i][j-1] + mat[4][to(b[j])]  );    
            }
        }
        printf("%d",dp[an][bn]);
        return 0;
    }
    View Code

    理解: 在边界条件的限制下,有三种情况:

    1. 当前基因与对象基因进行匹配,        =dp[i-1][j-1]+f(i,j)

    2. 当前基因放弃匹配,插入一个“-”(空符号)   =dp[i-1][j]+f(i,∅)

    3. 对象基因放弃匹配,插入一个“-”(空符号)   =dp[i][j-1]+f(∅,j)

    基本思路与LCS相同


  • 相关阅读:
    Java学习01-使用maven插件tomcat搭建web maven项目
    Anaconda3安装及使用
    python标准日志模块logging及日志系统设计
    python traceback捕获并打印异常
    python time
    PIL 中的 Image 模块
    python zipfile使用
    PHP 判断用户是否手机访问
    php数组相加 两个数组键名相同 后者不能覆盖前者
    解决Ubuntu Server 12.04换了网卡MAC地址后 网络不可用的问题.
  • 原文地址:https://www.cnblogs.com/TQCAI/p/8427862.html
Copyright © 2020-2023  润新知