私は最近、動的プログラミングについて読んでいます。ゼロから始めて、現在DP問題の特定と解決が得意な人の話を聞きたいです。私はこれらの問題をDPとして特定し、簡潔な解決策を組み立てるのに苦労しています。
私は初心者のDPの問題とMITのリソースなどのほとんどを経験しました
私は最近、動的プログラミングについて読んでいます。ゼロから始めて、現在DP問題の特定と解決が得意な人の話を聞きたいです。私はこれらの問題をDPとして特定し、簡潔な解決策を組み立てるのに苦労しています。
私は初心者のDPの問題とMITのリソースなどのほとんどを経験しました
回答:
私は物理学のバックグラウンドを持っているため、多くの数学を学んでいます。帰納法による証明との類似性を見つけることにより、再帰的/動的プログラミングソリューションに適した問題を簡単に見つけることができます。
帰納法による証明には、2つの部分があります。
再帰プログラミング/動的プログラミングの場合:
だから、他の人が答えたように、それは経験とヒントを選ぶことの問題ですが、あなたはあなたを導くために他のスキルを再利用することができます。その後、私が述べた2つの部分を常に持っている必要があります。そうでない場合、機能しません。
たとえば、セットのすべての順列を生成するには:
ほとんどの動的プログラミングの問題は、メモ化によって解決できます。メモ化は通常、より直感的でコーディングが簡単です。DPではなく、メモ化の観点から考えると役立つ場合があります。
通常、問題がメモ化に適しているかどうかを判断する方が簡単です(手順はSlivvzの答えと同じですが、精神的な変化は少し短いと思います)。ただし、メモ化によって問題を解決したら、再帰なしでメモキャッシュがどのように満たされているかを調べ、順番に埋めることができます。これにより、アルゴリズムが動的プログラミングアルゴリズムに変更されます。
TL; DR; バージョン:メモ化の観点から動的プログラミングを理解する方が簡単な場合があります。
StackOverflow:動的プログラミングとメモ化:ボトムアップアプローチとトップダウンアプローチも参照してください。
動的プログラミングは、定義上、次の2つのことについてです。
最適な下部構造
小さいソリューションから大きいソリューションを派生させることができます。解決は双方向ではありません。
重複するサブ問題
小さなソリューションは何度も再利用されます。サブ問題がまったく重ならない場合、DP /メモ化の恩恵を受けません。あなたが持っているのは、代わりに分割して征服することです。
DP問題への一般的なアプローチは次のとおりです。
動作するナイーブな再帰バージョンまたは反復バージョンを作成します。
関数が冗長な作業を行っていることに注意してください。
多くの場合、メモによって、その冗長な作業を回避する方法を見つけます。
数年前にプロジェクトオイラーの問題を始めたときまで、動的プログラミングソルバーを1つも実装したことはありませんでした。そこDP-解ける問題(例えば76、158、161、242、しかし、もっとたくさんあります)私のお気に入りの種類であることがわかりました それが有用なテクニックになるとき、あなたは間違いなくスポッティングで良くなります:基本的に、必要な経路の爆発を飼いならすことができるある種の再帰的な分割統治アプローチによって解決できるように見えるものを探します繰り返し発生するサブ問題を認識し、以前に計算された結果を再利用することにより調査されます。最小限の状態ベクトルを識別してメモできること、および無関係な「履歴」を消去できることは重要なステップです。