Palíndromo dividido

Palíndromo dividido

Descrição do título

Dada uma string, retorna o número mínimo de cortes que cortam todas as str em strings de palíndromo.

Insira uma descrição:

A entrada contém uma linha de string, representando str (1 ≤ lengthstr ≤ 5000) str (1 \ leq length_ {str} \ leq 5000)s t r ( 1l e n g t hs t r5 0 0 0 )

Descrição de saída:

Produza um inteiro, representando o número mínimo de cortes para cortar todas as str em strings de palíndromo.

Exemplo 1
entrar
ABA
Resultado
0
Descrição
本身是回文串,不需要切割,直接输出0
Exemplo 2
entrar
ABCBAEEE
Resultado
1
Descrição
切割1次,变为“ABCBA”和“EEE”
Observações:

Complexidade de tempo O (n 2) O (n ^ 2)O ( n2 ), complexidade de espaço adicionalO (n 2) O (n ^ 2)O ( n2 )


responda:

Programaçao dinamica. Deixe F [i] denotar que str [0 ... i] precisa ser dividido pelo menos várias vezes antes que todo str [0 ... i] possa ser dividido em strings de palíndromo. Calcule F [i] da esquerda para a direita, o processo é o seguinte:

  • Suponha que a posição atual seja j (j <= i <len), se str [j ... i] for um palíndromo, então F [i] = F [j-1] +1, o que significa em str [0 ... i] Na substring, str [j ... i] já é uma string de palíndromo, é usada como uma parte separada, e o resto usa seu número mínimo de divisões de palíndromo, a saber F [j-1];
  • Deixe j enumerar de 0 a i, encontre o valor mínimo em todos os casos, ou seja, F [i] = min {F [j-1] +1 (0 <= j <= i <len, e str [ j ... i] é um palíndromo)};
  • Para determinar rapidamente se str [j ... i] é um palíndromo, o processo é o seguinte:
    • Defina uma matriz bidimensional p, p [j] [i] = truep [j] [i] = truep [ j ] [ i ]=t r u e significa str [j ... i] é um palíndromo;
    • p [j] [i] = verdadeirop [j] [i] = verdadeirop [ j ] [ i ]=t r u e deve ser os seguintes três casos:
      • str [j ... i] tem apenas um caractere;
      • str [j… i] tem dois caracteres e os dois caracteres são iguais;
      • str [j + 1 ... i-1] é uma string palíndromo, ou seja, p [j + 1] [i - 1] = verdadeiro p [j + 1] [i-1] = verdadeirop [ j+1 ] [ i-1 ]=t r u e, 且 str [j] == str [i] ;
  • i vai da esquerda para a direita, j vai da direita para a esquerda, então p [j + 1] [i - 1] p [j + 1] [i-1]p [ j+1 ] [ i-1 ] Deve ter sido calculado.
Código:
#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;
}

Acho que você gosta

Origin blog.csdn.net/MIC10086/article/details/108998062
Recomendado
Clasificación