First find all the palindromes in the string such that L[i][j] represents the length of j-th longest palindrome that ends at S[i]. Lets say S is the input string. This could be done in O(N^2) time by first considering length1 palindromes then then length 2 palindromes and so on.
Finding Length i palindromes after you know all length i-2 palindromes is the matter of a single character comparison.
This is a dynamic programming problem after that. Let A[i] represent the smallest number of palindrome that Substring(S,0,i-1) can be decomposed into.
A[i+1] = min_{0 <= j < length(L[i])} A[i - L[i][j]] + 1;
Edit based on Micron's request:
Here is the idea behind comuting L[i][j]. I just wrote this up to convey the idea, the code may have problems.
// 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);
}
}
}
}