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

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

时间:2020-02-28 23:08:46      阅读:121      评论:0      收藏:0      [点我收藏+]

标签:要求   color   lan   code   col   div   http   void   序列   

没有要求输出最优解:  题目链接: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  } 

 

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

标签:要求   color   lan   code   col   div   http   void   序列   

原文地址:https://www.cnblogs.com/tflsnoi/p/12380571.html

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