I have seen various discussions and code attempts at solving the "String reduction" problem from interviewstreet.com, but none of them does it via dynamic programming.
Listed under the Dynamic Programming section, the problem is described as follows:
Given a string consisting of a,b and c’s, we can perform the following operation: Take any two adjacent distinct characters and replace it with the third character. For example, if ‘a’ and ‘c’ are adjacent, they can replaced with ‘b’.
What is the smallest string which can result by applying this operation repeatedly?
The problem can be solved using exhaustive brute-force search, effectively creating a tree of all possible substitutions:
// this is more or less pseudo code from my head
int GetMinLength(string s)
{
// solve edge cases
if (s.Length == 1) return 1;
if (s.Length == 2) return ReduceIfPossible(s);
// recursive brute force
int min = s.Length;
for (int i = 0; i<s.Length-1; i++)
{
if (s[i] != s[i+1])
{
var next = GetMinLength(
s.Substring(0, i) +
Reduce(s[i], s[i + 1]) +
s.Substring(i + 2)
);
if (next < min) min = next;
}
}
}
This obviously fails for larger N (N <= 100), so I am trying to break it into smaller subproblems, memoize them, and merge results.
The problem is that I cannot determine the state which would have "optimal substructure", needed to apply dynamic programming (or in other words to "merge" results from sub-problems). Minimizing a part of the string doesn’t guarantee that the final string will really be the smallest solution.
What would be the subproblem "state" in this case, which could be merged towards the final solution?
What makes this tricky is that you need to treat this as 2 dynamic programming problems in a row.
icharacters of the string can be reduced to. (The table that you built in step 1 can be used to recursively reduce this problem to already solved subproblems.)The second provides your answer. It is much more straightforward if you have already solved the first.