[EDIT 10/19/2015: an anonymous reviewer pointed out a problem with the formula that prompted me to notice another, even bigger mistake ... Now fixed.]
Now I see how to reduce the solution time to O (n ^ 2) . I will leave my other answer in case this is interesting, as a stepping stone to this. Note. This (also) solution is only for the first part of the problem; I do not see the ability to efficiently count only individual palindromic subsequences (PS).
Instead of counting the number of PSs that begin and end exactly at positions i and j, let them count how many starts with or after i and end at or before j. Call it g (i, j).
We can try to write g (i, j) = g (i, j-1) + g (i + 1, j) + (x [i] == x [j]) * g (i + 1, j- 1) for the case j> i. But that didn’t work, because the first two members will count twice any PS that starts after i and ends before j.
The key insight is to notice that we can easily calculate the number of PSs that start or end at some exact position by subtracting other g () values and possibly adding even more g () values to compensate for double counting. For example, the number of PS starting with exactly i and ending exactly in j is g (i, j) - g (i + 1, j) - g (i, j-1) + g (i + 1, j -1 ): the last term corrects the fact that both the second and third terms count all g (i + 1, j-1) PS, which begin after i and end before j.
Each PS starting with or after i and ending before or before j is in exactly 1 of 4 categories:
- It starts after i and ends before j.
- It starts with i and ends with j.
- It starts after i and ends on j.
- It starts with i and ends with j.
g (i + 1, j) counts all PSs in categories 1 or 3, and g (i, j-1) counts all PSs in categories 1 or 2, so their sum g (i + 1, j) + g (i , j-1) counts all PSs in category 2 or 3 once, and all PSs in category 1 twice. Since g (i + 1, j-1) counts all PSs only in category 1, subtracting this to get g (i + 1, j) + g (i, j-1) - g (i + 1, j- 1) gives the total number of PSs in categories 1, 2 and 3. The remaining PSs are those in category 4. If x [i]! = X [j], then this category does not have PS; otherwise, there are exactly the same number of PSs that begin with or after i + 1 and end before or before j-1, namely g (i + 1, j-1), plus one extra for a 2-character sequence x [I] x [J]. [EDIT: Thanks to Tuxdude commentator for 2 fixes here!]
With this in mind, we can express g () in such a way as to change the quadratic case from f () to constant time:
g(i, i) = 1 (ie when j = i) g(i, i+1) = 2 + (x[i] == x[i+1]) (ie 3 iff adjacent chars are identical, otherwise 2) g(i, j) = 0 when j < i (this new boundary case is needed) g(i, j) = g(i+1, j) + g(i, j-1) - g(i+1, j-1) + (x[i] == x[j])*(g(i+1, j-1)+1) when j >= i+2
The final answer is now just g (1, n).