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