动态规划的部分是两道题,又找了些相关的题
1.最长公共子序列(不要求连续)
一道基本的动态规划
dp[i][j]表示text1第i个字符和text2第j个字符之前的公共最长子序列的长度
根据text1[i]与text2[j]是否相同分为以下两种情况:
1.若text1[i] == text2[j],则dp[i][j] = dp[i-1][j-1] + 1;
2.若text1[i] != text2[j],则dp[i][j] = max(dp[i-1][j], dp[i][j-1])。
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
int a=text1.size();
int b=text2.size();
vector<vector<int>> dp(a+1,vector(b+1,0));
for(int i=1;i<=a;i++){
for(int j=1;j<=b;j++){
if(text1[i-1]==text2[j-1])
dp[i][j]=dp[i-1][j-1]+1;
else
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
return dp[a][b];
}
};
2.最长公共连续子序列
若a[i] == b[j],则dp[i][j] = dp[i-1][j-1] + 1;
若a[i] != b[j],则dp[i][j] = 0
注意设置边界值
#include<vector>
#include<iostream>
#include<string>
using namespace std;
int func(string a,string b) {
int lena = a.size();
int lenb = b.size();
vector<vector<int>> dp(lena, vector<int>(lenb, 0));
for (int i = 0; i < lena; i++)
dp[i][0] = a[i] == b[0] ? 1 : 0;
for (int j = 0; j < lenb; j++)
dp[0][j] = b[j] == a[0] ? 1 : 0;
int length = 0, index = 0;
for (int i = 1; i < lena; i++) {
for (int j = 1; j < lenb; j++) {
if (a[i] == b[j]) dp[i][j] = dp[i - 1][j - 1] + 1;
if (dp[i][j] > length) {
length = dp[i][j];
index = i;
}
}
}
string res = "";
for (int i = index - length + 1; i < length; i++) res += a[i];
cout << "最长连续的公共子序列为:" << res << endl;
return length;
}
int main() {
string a, b;
/*
cout << "请输入字符串a:" << endl;
cin >> a;
cout << "请输入字符串b:" << endl;
cin >> b;
*/
a = "abcednjcdj";
b = "njcnkabced";
int c = func(a, b);
cout << "最长连续子序列的长度为:" << c << endl;
return 0;
}
3.最长回文子序列
dp[i][j]表示字符串中i~j的最长回文子序列的长度
dp[i][i]=1
class Solution {
public:
int longestPalindromeSubseq(string s) {
int n=s.size();
vector<vector<int>> dp(n,vector<int>(n,0));
for(int i=n-1;i>=0;i--){
dp[i][i]=1;
for(int j=i+1;j<n;j++){
if(s[i]==s[j]) dp[i][j]=dp[i+1][j-1]+2;
else dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
}
}
return dp[0][n-1];
}
};
dp[i][j]:如果i~j是回文的,则为true
class Solution {
public:
string longestPalindrome(string s) {
int n=s.size();
if(n<=1) return s;
vector<vector<bool>> dp(n,vector<bool>(n,false));
int index=0,length=1;
for(int i=n-1;i>=0;i--){
dp[i][i]=true;
for(int j=i+1;j<n;j++){
dp[i][j]=(s[i]==s[j]&&(j-i<3||dp[i+1][j-1]));
if(dp[i][j]&&length<j-i+1){
index=i;
length=j-i+1;
}
}
}
return s.substr(index,length);
}
};