• 经典题--最长公共子序列(LCS)


    没有要求输出最优解:  题目链接:http://ybt.ssoier.cn:8088/problem_show.php?pid=1265

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 char x[1005], y[1005];
     4 int lx, ly, dp[1005][1005];
     5 
     6 void init(){
     7     //初始化,这个初始化是针对dp表的 
     8     for(int i=0; i<=lx; i++)dp[i][0]=0;
     9     for(int i=0; i<=ly; i++)dp[0][i]=0;
    10 }
    11 void lcs(){
    12     for(int i=1; i<=lx; i++){
    13         for(int j=1; j<=ly; j++){
    14             if(x[i-1]==y[j-1])//注意这个细节,容易出错 
    15                 dp[i][j]=dp[i-1][j-1]+1; 
    16             else
    17                 dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
    18             //cout<<dp[i][j]<<" ";//测试所用 
    19         }
    20         //cout<<endl;//测试所用 
    21     }
    22 }
    23 int main()
    24 {
    25     cin>>x>>y;
    26     lx=strlen(x), ly=strlen(y);
    27     init();
    28     lcs();
    29     cout<<dp[lx][ly];
    30     return 0;
    31  } 

    要求输出最优解:  题目链接:https://www.51nod.com/Challenge/Problem.html#problemId=1006

    方法一:用t[][]数组记录路径

     1 //最长公共子序列输出方法一 
     2 #include<bits/stdc++.h>
     3 using namespace std;
     4 char x[1005], y[1005];
     5 int lx, ly, dp[1005][1005];
     6 int t[1005][1005]; //用于记录选择路径,分别用1,2,3记录是从哪来的 
     7 
     8 void init(){
     9     //初始化,这个初始化是针对dp表的 
    10     for(int i=0; i<=lx; i++)dp[i][0]=0;
    11     for(int i=0; i<=ly; i++)dp[0][i]=0;
    12 }
    13 void lcs(){
    14     for(int i=1; i<=lx; i++){
    15         for(int j=1; j<=ly; j++){
    16             if(x[i-1]==y[j-1]){//注意这个细节,容易出错 
    17                 dp[i][j]=dp[i-1][j-1]+1;
    18                 t[i][j]=1; //从左上(i-1,j-1)转移用1表示
    19             }
    20             else{
    21                 if(dp[i-1][j]>=dp[i][j-1]){
    22                     dp[i][j]=dp[i-1][j];
    23                     t[i][j]=2;//从上(i-1,j)转移用2表示
    24                 }
    25                 else{
    26                     dp[i][j]=dp[i][j-1];
    27                     t[i][j]=3;//从左(i,j-1)转移用2表示     
    28                 }
    29             }     
    30         }
    31     }
    32 }
    33 void print(int i, int j)//递归输出t[][]数组最优解 
    34 {
    35     if(i==0 || j==0)return;
    36     
    37     if(t[i][j]==1){
    38         print(i-1, j-1);
    39         cout<<x[i-1];
    40     }
    41     else if(t[i][j]==2)print(i-1,j);
    42     else print(i,j-1);
    43 }
    44 int main()
    45 {
    46     cin>>x>>y;
    47     lx=strlen(x), ly=strlen(y);
    48     init();//初始化 
    49     lcs();//求ans 
    50     cout<<dp[lx][ly]<<endl;
    51     print(lx, ly);//打印最优解 
    52     return 0;
    53  } 

    方法二:根据转移方程递归输出数组最优解

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 char x[1005], y[1005];
     4 int lx, ly, dp[1005][1005];
     5 
     6 void init(){
     7     //初始化,这个初始化是针对dp表的 
     8     for(int i=0; i<=lx; i++)dp[i][0]=0;
     9     for(int i=0; i<=ly; i++)dp[0][i]=0;
    10 }
    11 void lcs(){
    12     for(int i=1; i<=lx; i++){
    13         for(int j=1; j<=ly; j++){
    14             if(x[i-1]==y[j-1])//注意这个细节,容易出错 
    15                 dp[i][j]=dp[i-1][j-1]+1; 
    16             else
    17                 dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
    18             //cout<<dp[i][j]<<" ";//测试所用 
    19         }
    20         //cout<<endl;//测试所用 
    21     }
    22 }
    23 void print(int i, int j){//根据转移方程递归输出数组最优解 
    24     if(i==0 || j==0)return;
    25     if(x[i-1]==y[j-1]){
    26         print(i-1,j-1);
    27         cout<<x[i-1];
    28     } 
    29     else{
    30         if(dp[i-1][j]>=dp[i][j-1])
    31             print(i-1,j);
    32         else 
    33             print(i,j-1);
    34     }
    35 }
    36 int main()
    37 {
    38     cin>>x>>y;
    39     lx=strlen(x), ly=strlen(y);
    40     init();
    41     lcs();
    42     cout<<dp[lx][ly];
    43     print(lx, ly);//打印最优解 
    44     return 0;
    45  } 
  • 相关阅读:
    delphi调用存储过程
    mysql存储过程中使用事务
    高性能JAVA开发之内存管理
    高效的找出两个List中的不同元素
    The reference to entity "characterEncoding" must end with the ';' delimiter
    Maven的安装、配置及使用入门
    如何在电脑上测试手机网站(全)
    三种常用的js数组去重方法
    oracle ORA-01461 错误 can bind a LONG value only for insert into a LONG column
    windows cmd下netstat查看占用端口号的进程和程序
  • 原文地址:https://www.cnblogs.com/tflsnoi/p/12380571.html
Copyright © 2020-2023  润新知