Сначала найдите все палиндромы в строке, так что L [i] [j] представляет длину j-го самого длинного палиндрома, который заканчивается в S [i].Допустим, S является входной строкой.Это можно сделать за O (N ^ 2), сначала рассмотрев палиндромы длины 1, затем палиндромы длины 2 и так далее.Поиск длины i палиндромов после того, как вы знаете всю длину i-2 палиндромов, это вопрос сравнения одного символа.
Это проблема динамического программирования после этого.Пусть A [i] представляет наименьшее число палиндромов, на которое может быть разложена подстрока (S, 0, i-1).
A[i+1] = min_{0 <= j < length(L[i])} A[i - L[i][j]] + 1;
Редактирование на основе запроса Микрона: Вот идея, лежащая в основе вычисления L [i] [j].Я просто написал это, чтобы передать идею, код может иметь проблемы.
// Every single char is palindrome so L[i][0] = 1;
vector<vector<int> > L(S.length(), vector<int>(1,1));
for (i = 0; i < S.length(); i++) {
for (j = 2; j < S.length; j++) {
if (i - j + 1 >= 0 && S[i] == S[i-j + 1]) {
// See if there was a palindrome of length j - 2 ending at S[i-1]
bool inner_palindrome = false;
if (j ==2) {
inner_palindrome = true;
} else {
int k = L[i-1].length;
if (L[i-1][k-1] == j-2 || (k >= 2 && L[i-1][k-2] == j-2)) {
inner_palindrome = true;
}
}
if (inner_palindrome) {
L[i].push_back(j);
}
}
}
}