【发布时间】:2012-06-29 23:27:09
【问题描述】:
我在 interviewstreet.com 上看到过各种讨论和尝试解决"String reduction" 问题的代码,但没有一个是通过动态编程实现的。
列在Dynamic Programming部分下,问题描述如下:
给定一个由 a、b 和 c 组成的字符串,我们可以执行以下操作:取任意两个相邻的不同字符并将其替换为第三个字符。例如,如果“a”和“c”相邻,则可以将它们替换为“b”。
重复应用此操作可以得到的最小字符串是多少?
可以使用穷举蛮力搜索来解决问题,有效地创建所有可能替换的树:
// 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;
}
}
}
这对于较大的N (N <= 100) 显然会失败,所以我试图将其分解为更小的子问题,记忆它们并合并结果。
问题是我无法确定具有"optimal substructure" 的状态,需要应用动态编程(或者换句话说,“合并”来自子问题的结果)。将字符串的一部分最小化并不能保证最终的字符串确实是最小的解决方案。
在这种情况下,什么是子问题“状态”,可以合并到最终解决方案中?
【问题讨论】:
标签: algorithm dynamic-programming