zoukankan      html  css  js  c++  java
  • 最长公共子序列hdu1503

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1503

    题意:给你两个字符串,把这两个字符串合并,使合并之后的字符串最短,并且合并之后的字符之间的相对位置和在原字符串中的相对位置相同,其实意思就是叫我们求最长公共子序列,主要是输出的顺序,一开始不知道要保持相对位置不变,后面百度了才知道。

    具体思路就是dp+DFS,dp是计算最长公共子序列的长度和求最长公共子序列时走过的路径,DFS是用来输出答案并保持相对位置不变。

    具体看代码:

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<stack>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<cstdio>
    #include<string>
    #include<deque> 
    using namespace std;
    typedef long long LL;
    #define eps 1e-8
    #define INF 0x3f3f3f3f
    #define maxn 1005
    /*struct point{
        int u,w;
    };
    bool operator <(const point &s1,const point &s2)
    {
        if(s1.w!=s2.w)
        return s1.w>s2.w;
        else
        return s1.u>s2.u;
    }*/
    int dp[105][105];
    int n,m,k,t;
    char str1[105],str2[105];
    int path[105][105];//记录在求LCS时的路径 
    void DFS(int a,int b)
    {
        if(a==-1&&b==-1)//终止条件 
        return;
        if(path[a+1][b+1]==1)
        {
            DFS(a-1,b-1);//往对角线方向走 
            cout<<str1[a];
        }
        else if(path[a+1][b+1]==2)
        {
            DFS(a,b-1);//往左走 
            cout<<str2[b];
        }
        else
        {
            DFS(a-1,b);//往上 
            cout<<str1[a];
        }
    }
    int main()
    {
        while(scanf("%s %s",str1,str2)!=EOF)
        {
            int len1=strlen(str1);
            int len2=strlen(str2);
            memset(dp,0,sizeof(dp));
            for(int i=0;i<=len1;i++)
            path[i][0]=3;//往上走,直到开头 
            for(int i=0;i<=len2;i++)
            path[0][i]=2;//往左走 
            for(int i=0;i<len1;i++){//因为字符串从0开始,但是dp下标是从1开始,所以dp下标加1 
                for(int j=0;j<len2;j++){
                    if(str1[i]==str2[j])
                    {
                        dp[i+1][j+1]=max(dp[i+1][j+1],dp[i][j]+1);
                        path[i+1][j+1]=1;//往对角线方向 
                    }
                    else if(dp[i+1][j]>dp[i][j+1])
                    {
                        dp[i+1][j+1]=dp[i+1][j];
                        path[i+1][j+1]=2;//往左走 
                     }
                     else
                     {
                         dp[i+1][j+1]=dp[i][j+1];
                         path[i+1][j+1]=3;//往上走 
                      } 
                }
            }
            DFS(len1-1,len2-1);//输出答案,从两个字符串的结尾DFS 
            printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    记一次CTF出题WP
    markdown测试
    高强度学习训练第二天总结:Opencv+Android+CameraView小demo
    高强度学习训练第一天总结:Java内存区域
    黑客中最受欢迎的工具排行榜
    Java面试复习(纯手打)
    深度学习概论学习笔记
    TensorFlow、numpy、matplotlib、基本操作
    OpenCV 笔记
    Vue Stomp+SocketJS 数据报错[Object object]
  • 原文地址:https://www.cnblogs.com/6262369sss/p/9936718.html
Copyright © 2011-2022 走看看