Dynamic Programming (DP) of the LCS (Longest Common Subsequence) / the longest common subsequence

Problem Description:

Longest common subsequence. Given two sequences of length M and N, respectively, a and b of the string, and the demand not only a character string length is the longest sequence of b is.

Status means:

f [i] [j] represents the prefix string of a [1 ~ i] length "longest common subsequence" and the b [1 ~ j] of.

Phasing:

Already processed prefix length (the position of two strings, i.e., a two-dimensional coordinate system)

Transfer equation:

f[i,j]=max{f[i-1,j],fg[i,j-1]}  a[i]!=b[j]

f[i,j]=max{f[i-1,j],f[i,j-1],f[i-1,j-1]+1}  a[i]=b[j]

boundary:

f[i,0]=f[0,j]=0

aims:

f[M,N]

Code to achieve 1:

#include<bits/stdc++.h>
using namespace std;
string a;
string b;
int s[1111][1111];
int main(){
	cin>>a>>b;
	int x=a.size();
	int y=b.size();
	for(int i=1;i<=x;i++){
		for(int j=1;j<=y;j++){
			if(a[i-1]==b[j-1]){
				s[i][j]=max(s[i][j],s[i-1][j-1]+1);
			}else{
				s[i][j]=max(s[i][j-1],s[i-1][j]);
			}
		}
	}
	cout<<s[x][y];
	return 0;
}

In the following code, g [i, j] indicates a transition from where

2 code implements (printing passes):

Write a function for recursive output

#include<bits/stdc++.h>
using namespace std;
char a[1111],b[1111];
int f[1111][1111];
int g[1111][1111];
void s(int i,int j){
	if(i==0||j==0){
		return;
	}
	if(!g[i][j]){
		s(i-1,j-1);
		cout<<a[i-1];
	}else if(g[i][j]==1){
		s(i-1,j);
	}else if(g[i][j]=-1){
		s(i,j-1);
	}
}
int main(){
	cin>>a>>b;
	int lena=strlen(a);
	int lenb=strlen(b);
	for(int i=1;i<=lena;i++){
		for(int j=1;j<=lenb;j++){
			if(a[i-1]==b[j-1]){
				f[i][j]=f[i-1][j-1]+1;
				g[i][j]=0;
			}else{
				if(f[i-1][j]>f[i][j-1]){
					f[i][j]=f[i-1][j];
					g[i][j]=1;
				}else{
					f[i][j]=f[i][j-1];
					g[i][j]=-1;
				}
			}
		}
	}
	s(lena,lenb);
	return 0;
}

Code implements 3 (printing passes):

Reverse backtracking, using the stack storage path

#include<bits/stdc++.h>
using namespace std;
char a[1111],b[1111],c;
int f[1111][1111];
int main(){
	cin>>a>>b;
	int la=strlen(a);
	int lb=strlen(b);
	for(int i=1;i<=la;i++){
		for(int j=1;j<=lb;j++){
			if(a[i-1]==b[j-1]){
				f[i][j]=f[i-1][j-1]+1;
			}else{
				f[i][j]=max(f[i-1][j],f[i][j-1]);
			}
		}
	}
	int i=la,j=lb;
	stack<char>s;
	while(f[i][j]){
		if(f[i][j]==f[i-1][j]){
			i--;
		}else if(f[i][j]==f[i][j-1]){
			j--;
		}else if(f[i][j]>f[i-1][j-1]){
			i--;
			j--;
			s.push(a[i]);
		}
	}
	while(!s.empty()){
		c=s.top();
		cout<<c;
		s.pop();
	}
	return 0;
}

Guess you like

Origin www.cnblogs.com/hazel-wu/p/11298364.html