Palindrome split

Palindrome split

Title description

Given a string, return the minimum number of cuts that cut all str into palindrome strings.

Enter a description:

The input contains a line of string, representing str (1 ≤ lengthstr ≤ 5000) str(1 \leq length_{str} \leq 5000)str(1lengthstr5000)

Output description:

Output an integer, representing the minimum number of cuts to cut all str into palindrome strings.

Example 1
enter
ABA
Output
0
Description
本身是回文串,不需要切割,直接输出0
Example 2
enter
ABCBAEEE
Output
1
Description
切割1次,变为“ABCBA”和“EEE”
Remarks:

Time complexity O (n 2) O(n^2)O ( n2 ), additional space complexityO (n 2) O(n^2)O ( n2)


answer:

Dynamic programming. Let F[i] denote that str[0...i] needs to be split at least several times before all str[0...i] can be split into palindrome strings. Calculate F[i] from left to right, the process is as follows:

  • Suppose the current position is j(j<=i<len), if str[j...i] is a palindrome, then F[i]=F[j-1]+1, which means in str[0...i] On the substring, str[j...i] is already a palindrome string, it is used as a separate part, and the rest uses its minimum number of palindrome divisions, namely F[j-1];
  • Let j enumerate from 0 to i, find the minimum value in all cases, that is, F[i]=min{F[j-1]+1(0<=j<=i<len, and str[ j...i] is a palindrome)};
  • To quickly determine whether str[j…i] is a palindrome, the process is as follows:
    • Define a two-dimensional array p, p [j] [i] = truep[j][i]=truep[j][i]=t r u e stands for str[j...i] is a palindrome;
    • p [ j ] [ i ] = t r u e p[j][i]=true p[j][i]=t r u e must be the following three cases:
      • str[j…i] has only one character;
      • str[j…i] has two characters and the two characters are equal;
      • str[j+1…i-1] is a palindrome string, that is, p [j + 1] [i − 1] = true p[j+1][i-1]=truep[j+1][i1]=true ,且 str[j]==str[i];
  • i goes from left to right, j goes from right to left, so p [j + 1] [i − 1] p[j+1][i-1]p[j+1][i1 ] Must have been calculated.
Code:
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 5005;

char s[N];
bool p[N][N];
int f[N];

int main(void) {
    
    
    scanf("%s", s);
    int n = strlen(s);
    for ( int i = 1; i < n; ++i ) {
    
    
        f[i] = i;
        for ( int j = i; j >= 0; --j ) {
    
    
            if ( s[i] == s[j] && ( i-j<2 || p[j+1][i-1] ) ) {
    
    
                p[j][i] = true;
                if (!j) f[i] = 0;
                else f[i] = min(f[i], f[j - 1] + 1);
            }
        }
    }
    printf("%d\n", f[n - 1]);
    return 0;
}

Guess you like

Origin blog.csdn.net/MIC10086/article/details/108998062