给定一个字符串s,你可以从中删除一些字符,使得剩下的串是一个回文串。如何删除才能使得回文串最长呢? 输出需要删除的字符个数。

链接: https://www.nowcoder.com/questionTerminal/28c1dc06bc9b4afd957b01acdf046e69
来源:牛客网

#include
#include
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 ;
}

你可能感兴趣的:(c++,常见算法的实现)