ダイナミックプログラミング
11189 ワード
ダイナミックプログラミング
最近は就職準備の過程でアルゴリズムを勉強していますが、最近はアルゴリズムを勉強する方法が間違っていることに気づき、勉強方法を変えたいと思います.タイプ学習から離れて、タイプに合った質問を20問ほど解いて、Verlogに文章を書いて、理解の程度を説明したので書きたいと思います.
動的プログラミングの基本概念は,重複する過程を探すことに重点を置いていると考えられる.
多くのことをやってみると(もちろん、もっと試してみる必要があります)、繰り返しのプロセスを見つけたとき、動的プログラミングの利点:繰り返しのプロセスのメモリに格納し、値を迅速に格納し、効率を向上させる点火式を確立することができます.まずコードで百聞は一見にしかずと教えてあげます.
以下はダイナミックプログラミング設計のFibonacciコードです.
次に、既存の再帰呼び出しのコードを示します.
さあ、Fibonacci関数に50を入れましょう!どうしてそんなに速いの?2番目の既存の再帰をFibonacciで呼び出すと、呼び出すたびに演算が行われ、時間がかかります.ただし、dp配列を使用すると、既存の演算プロセスの値が保存されるため、演算プロセスは行われず、その値のみが呼び出されて使用できます!すなわち,演算過程は消失する.
はい、しかし、実は、私も他のブログを見て、ここを見ても理解できませんでした.だから私は一つの問題を選んで、あなたに見せます.
白準アルゴリズム2156号-ワイン試飲
問題は簡単です.ワインの量を入力することができます.ワインは3つ連続で食べられません.(つまり、最大2個まで)このようにして最大の食べ方を見つけます.
連続して食べることができないので、図案は3つに統一されます.
食べます:YES、食べません:NO
自動プログラミングはこのような重複モードを見つけるために重要である.どうやってこれを設計すればいいのでしょうか?今はそれらのパターンの中で最大の値を与え続けるだけでいいです.
dp[0]Input[0]を指定します.
dp[1]Input[1]を指定します.
dp[2]はMathです.max(dp[1].Math.max(array[0]+array[2],array[1]+array[2])として指定します.上の図案をそのままメモして、3つ目を先に求めます.
今から3つ目から、上の式を直接Nに変えます.
dp[N] = Math.max(dp[N-1]. Math.max(dp[N-2] + array[i] , dp[N-3] + array[N-1] + array[N])); 今ではデザイン通りに解答すれば、答えが出ます.
public class Back2156 {
static int[] dp;
static int[] array;
static int N;
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
N = scan.nextInt();
dp = new int[N];
array = new int[N];
for(int i = 0; i<N; i++){
array[i] = scan.nextInt();
}
if(N >= 1){
dp[0] = array[0];
}
if(N >= 2){
dp[1] = dp[0] +array[1];
}
if(N >= 3){
dp[2] = Math.max(dp[1], Math.max(array[0]+array[2] , array[1]+array[2]));
}
for(int i = 3; i<N; i++){
dp[i] = Math.max(dp[i-1], Math.max(dp[i-2] + array[i] , dp[i-3] + array[i-1] + array[i]));
}
System.out.println(dp[N-1]);
scan.close();
}
}
私は私が理解できる問題で解決してみました.もしあなたが理解しなければ、私はあなたがこのような方法でプロセスを最適化することを望んでいます.簡単な問題から始めます.Reference
この問題について(ダイナミックプログラミング), 我々は、より多くの情報をここで見つけました https://velog.io/@tmdgusya/동적-프로그래밍テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol