LCS最长公共子序列
思路:dp
//状态转移方程:
//dp[]储存 当前最长公共子序列的长度
//假设z[]为最长公共子序列
1.a[i]=b[j] dp[i][j] = dp[i-1][j-1]+1
//因为a[i]=b[j],所以a[i]=b[j]=z[len] 所以dp[i][j] = dp[i-1][j-1]+1
2.a[i]!=b[j] && z[k]!=a[i] 所以dp[i][j] = dp[i-1][j] ,即a[i]对dp[i][j]无影响
3.a[i]!=b[j] && z[k]!=b[j] 所以dp[i][j] = dp[i][j-1] ,同上
//合并2/3,得:若a[i]!=b[j] 则dp[i][j] = max(dp[i-1][j],dp[i][j-1])
//因为所求为最长 ,所以在2、3两种可能的情况中取最大值
ps:因为要dp[i-1][j-1],又string从0开始,所以要dp后移一位
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std ;
const int maxn = 1e4+3 ;
int dp[maxn][maxn] ;
int main()
{
string a,b ;
while(cin>>a>>b)
{
int len1 = a.length() ;
int len2 = b.length() ;
for(int i = 0 ; i < len1 ; i++) dp[i][0] = 0 ;
for(int j = 0 ; j < len2 ; j++) dp[0][j] = 0 ;
for(int i = 0 ; i < len1 ; i++)
{
for(int j = 0 ; j < len2 ; j++)
{
if(a[i] == b[j]) dp[i+1][j+1] = dp[i][j]+1 ;
else dp[i+1][j+1] = max(dp[i][j+1],dp[i+1][j]) ;
}
}
printf("%d\n",dp[len1][len2]) ;
}
return 0 ;
}