题目链接:[ POJ - 1458 ]

题目大意

输入两个串s1,s2, 设MaxLen(i, j)表示:
s1的左边i个字符形成的子串,与s2左边的j个字符形成的子串的最长公共子序列的长度(i,j)从 0 开始
算)
MaxLen(i,j) 就是本题的“状态”

假定 len1 = strlen(s1)len2 = strlen(s2)
那么题目就是要求 MaxLen(len1, len2)

思路

显然: MaxLen(n,0) = 0 ( n= 0...len1) MaxLen(0,n) = 0 ( n=0...len2)
递推公式:

 if ( s1[i-1] == s2[j-1] ) //s1的最左边字符是s1[0]  
    MaxLen(i,j) = MaxLen(i-1,j-1) + 1;  
 else  
    MaxLen(i,j) = Max(MaxLen(i,j-1),MaxLen(i-1,j) );  

时间复杂度 $O(m \times n)$ m, n是两个字串长度

题解代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000 + 10;
int dp[maxn][maxn];
char a[maxn], b[maxn];

int main(void)
{
    while (cin >> a >> b) {
        memset(dp, 0, sizeof(dp));
        int len1 = strlen(a);
        int len2 = strlen(b);
        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]);
            }
        }
        cout << dp[len1][len2] << endl;
    }
        return 0;
}