找工作刷题记录_028最长公共子序列

刷题用C++吖吖!!!加油

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

输入例子:

abcda

google

输出例子:

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

猜你喜欢

转载自blog.csdn.net/qq_23565519/article/details/89010584