刷题用C++吖吖!!!加油
给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢?
输出需要删除的字符个数。
输入例子:
abcda
输出例子:
2
2
解题思路:
(1)把字符串旋转形成另外一个字符串,称为旋转字符串;
(2)求原字符串s1与旋转字符串s2中,最长公共子串的长度;
(3)删除的字符数目 = 原字符串的长度 - 最长公共子串的长度。
需要解决的子问题:
求两个字符串s1和s2中最长公共子串的长度。
子问题的求解方式:动态规划
#include <iostream>
#include <string>
using namespace std;
/*
解题思路:
(1)把字符串旋转形成另外一个字符串,称为旋转字符串;
(2)求原字符串s1与旋转字符串s2中,最长公共子串的长度;
(3)删除的字符数目 = 原字符串的长度 - 最长公共子串的长度。
需要解决的子问题:
求两个字符串s1和s2中最长公共子串的长度。
子问题的求解方式:动态规划
设 MaxLen(i,j)表示s1左边i个字符与s2左边j个字符的最长公共子串长度,则子问题的解为MaxLen(strlen(s1),strlen(s2));
MaxLen(i,j)的求解方式为:
若s1第i个字符与s2第j个字符相匹配,则 return 1+MaxLen(i-1,j-1);
否则:return max(MaxLen(i-1,j),MaxLen(i,j-1))
边界条件:
MaxLen(i,n)=0; for n in 0 to strlen(s2)
MaxLen(n,j)=0; for n in 0 to strlen(s1)
*/
#define __MAX_STR_LEN__ 1000
int max_len[__MAX_STR_LEN__][__MAX_STR_LEN__];
int main(){
string s1;
while(cin >> s1){
string s2(s1.rbegin(),s1.rend());
for(int i = 0; i < s1.length(); i++){
max_len[i][0] = 0;
max_len[0][i] = 0;
}
for(int i = 1; i <= s1.length(); i++)
for(int j = 1; j <= s2.length(); j++){
if(s1[i-1] == s2[j-1]){
max_len[i][j] = max_len[i-1][j-1]+1;
}
else
max_len[i][j] = max(max_len[i-1][j],max_len[i][j-1]);
}
cout << s1.length() - max_len[s1.length()][s2.length()] << endl;
}
return 0;
}