本题是利用动态规划的经典题目。首先需要注意的是,公共子串和公共子序列的区别,子串要求是连续的,而子序列不要求是连续的,要求的是相对位置不能错。
由于是连续的,所以我们以较短的字符串为基准(外循环),依次判断各个字符和较长的字符串的各个字符是否相等,如果相等则将dp数组的对应位置表示为dp[i-1][j-1]+1,否则为0。
同时不断更新和比较最大值(对角线上的最大值),并记录公共子序列的右端位置下标。
#include <iostream>
#include <string>
#include <vector>
using namespace std;

int main(){
    string s1, s2;
    getline(cin, s1, '\n');
    getline(cin, s2, '\n');
    
    int max = 0;
    int end = 0;
    int flag = 0;
	if (s1.size() <= s2.size()) flag = 1;
	string s11, s22;
	// 以较短的那个字符串作为判断的基准
	if (flag) {
		s11 = s1;
		s22 = s2;
	} else {
		s11 = s2;
		s22 = s1;
	}
    vector<vector<int>> dp(s11.size() + 1, vector<int>(s22.size() + 1, 0));
    for (int i = 1; i <= s11.size(); i++) {
        for (int j = 1; j <= s22.size(); j++) {
            if (s11[i - 1] == s22[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
                if (dp[i][j] > max) {
                max = dp[i][j];
                end = i - 1;
            }
            } else {
                dp[i][j] = 0;
            }
            
        }
    }
    string res;
	res = s11.substr(end - (max - 1), max);
	cout << res << endl;
    return 0;
}