私は、interviewstreet.com で「文字列削減」の問題を解決するためのさまざまな議論やコードの試みを見てきましたが、動的プログラミングを介してそれを行うものはありません。
動的プログラミングセクションの下にリストされている問題は、次のように説明されています。
a、b、c で構成される文字列が与えられた場合、次の操作を実行できます。隣接する 2 つの異なる文字を取り、3 番目の文字に置き換えます。たとえば、「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
、小さなサブ問題に分割し、それらをメモして、結果をマージしようとしています。
問題は、動的計画法を適用するために必要な「最適なサブ構造」を持つ状態を判断できないことです (つまり、サブ問題からの結果を「マージ」するために)。文字列の一部を最小化しても、最終的な文字列が実際に最小のソリューションになるとは限りません。
この場合、最終的な解決策にマージできる副問題の「状態」は何でしょうか?