zoukankan      html  css  js  c++  java
  • 51nod1006(lcs)

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1006

    题意:中文题诶~

    思路:最长公共子序列模板题~

    我们用dp[i][j]表示到a串第i个字符, b串第j个字符的最大匹配字符数,那么状态转移方程为:

    dp[i][j]=dp[i-1][j-1]+1      a[i]==b[j]

    dp[i][j]=max(dp[i][j-1], dp[i-1][j])   a[i]!=b[j]

    我们可以这样理解:dp[i][j]表示第a串前i个字符与b串前j个字符的最大匹配数,dp[i-1][j-1]表示a字符前i-1个字符与b串前j-1个字符的最大匹配数

    如果a[i]=b[j],那么很明显dp[i][j]=dp[i-1][j-1]+1;

    若a[i]!=b[j],我们假设a, b的最大匹配串为c,显然a[i], b[j]不能同时作为c的最后一个字符,那么最优匹配情况即为a[i]为c的最后一个字符或者b[j]为c的最后一个字符(这点不大好理解),即:

    dp[i][j]=dp[i][j-1]    a[i]是c的最后一个字符即匹配的末尾字符

    dp[i][j]=dp[i-1][j]    b[j]是c的最后一个字符即匹配的末尾字符 (其实当a[i], b[j]都不是c的最后一个字符时即a[i], b[j]都不匹配时dp[i][j]=dp[i-1][j-1])

    又dp要取最大值 ,即dp[i][j]=max(dp[i][j-1], dp[i-1][j])

    题目还要求要输出一个最优匹配串,这个我们用vis[][]数组在dp过程中记录一下路径就好啦~

    代码1:非递归取出路径

     1 #include <bits/stdc++.h>
     2 #define MAXN 1010
     3 using namespace std;
     4 
     5 int jj=0, vis[MAXN][MAXN];
     6 char gg[MAXN], a[MAXN], b[MAXN];
     7 
     8 void getlcs(int i, int j){  //**逆推取出vis中保存的路径
     9     while(i>0&&j>0){
    10         if(vis[i][j]==1){
    11             gg[jj++]=a[i-1];  //**将路径存储在gg数组中
    12             i--;
    13             j--;
    14         }else if(vis[i][j]==2){
    15             j--;
    16         }else if(vis[i][j]==3){
    17             i--;
    18         }
    19     }
    20     gg[jj]='';
    21 }
    22 
    23 int main(void){
    24     int dp[MAXN][MAXN];
    25     scanf("%s%s", a, b);
    26     int lena=strlen(a);
    27     int lenb=strlen(b);
    28     memset(vis, 0, sizeof(vis));
    29     memset(dp, 0, sizeof(dp));
    30     for(int i=1; i<=lena; i++){
    31         for(int j=1; j<=lenb; j++){
    32             if(a[i-1]==b[j-1]){
    33                 dp[i][j]=dp[i-1][j-1]+1;
    34                 vis[i][j]=1;              //**vis标记路径
    35             }else if(dp[i][j-1]>dp[i-1][j]){
    36                 dp[i][j]=dp[i][j-1];
    37                 vis[i][j]=2;
    38             }else{
    39                 dp[i][j]=dp[i-1][j];
    40                 vis[i][j]=3;
    41             }
    42         }
    43     }
    44     getlcs(lena, lenb);
    45     for(int i=jj-1; i>=0; i--){ //**输出路径
    46         printf("%c", gg[i]);
    47     }
    48     printf("
    ");
    49     return 0;
    50 }

    代码2: 递归输出路径

     1 #include <bits/stdc++.h>
     2 #define MAXN 1010
     3 using namespace std;
     4 
     5 int jj=0, vis[MAXN][MAXN];
     6 char a[MAXN], b[MAXN];
     7 
     8 void getlcs(int i, int j){ //**输出路径
     9     if(!i||!j){
    10         return;
    11     }
    12     if(vis[i][j]==1){
    13         getlcs(i-1, j-1);
    14         printf("%c", a[i-1]);
    15     }else if(vis[i][j]==2){
    16         getlcs(i, j-1);
    17     }else{
    18         getlcs(i-1, j);
    19     }
    20 }
    21 
    22 int main(void){
    23     int dp[MAXN][MAXN];
    24     scanf("%s%s", a, b);
    25     int lena=strlen(a);
    26     int lenb=strlen(b);
    27     memset(vis, 0, sizeof(vis));
    28     memset(dp, 0, sizeof(dp));
    29     for(int i=1; i<=lena; i++){
    30         for(int j=1; j<=lenb; j++){
    31             if(a[i-1]==b[j-1]){
    32                 dp[i][j]=dp[i-1][j-1]+1;
    33                 vis[i][j]=1;          //**vis标记路径
    34             }else if(dp[i][j-1]>dp[i-1][j]){
    35                 dp[i][j]=dp[i][j-1];
    36                 vis[i][j]=2;
    37             }else{
    38                 dp[i][j]=dp[i-1][j];
    39                 vis[i][j]=3;
    40             }
    41         }
    42     }
    43     getlcs(lena, lenb);
    44     printf("
    ");
    45     return 0;
    46 }
  • 相关阅读:
    头条java 后台一面凉经
    JVM运行时数据区
    基础篇——Spring Cloud Hystrix
    bug篇——idea拉取代码认证失败重新登录
    基础篇——代理模式之SpringAOP
    基础篇——代码优化100条之(11—20)
    电商项目实战(架构八)——RabbitMQ实现延迟消息
    电商项目实战(架构七)——Mongodb实现文档操作
    基础篇——代码优化100条之(1—10)
    电商项目实战(架构六)——Elasticsearch实现商品搜索
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/6160631.html
Copyright © 2011-2022 走看看