blog

データ構造とアルゴリズム - 動的計画法

動的計画法はアルゴリズム設計の手法の一つ。 問題を重複する部分問題に分解し、その部分問題を繰り返し解くことで、元の問題を繰り返し解くことによって、元の問題を解きます。 注:Divide and con...

Jun 23, 2020 · 2 min. read
シェア

動的計画法とは何ですか?

動的計画法は、アルゴリズム設計におけるアプローチの1つです。

問題を重複する部分問題に分解し、その部分問題を繰り返し解くことによって解きます。元の問題を解くために

注:Divide and conquerは、互いに独立した部分問題への分解を重視します。

フィボナッチ数列

部分問題の定義: F(n) = F(n-1) + F(n-2)

繰り返し:2からnまでループし、上式を実行

応用1:階段の上り下り

問題解決のアイデア

  • n段目に登るには、n-1段目で1段、n-2段目で2段登ります。
  • F(n) = F(n-1) + F(n-2)
  • 動的計画法の使用
/**
 * @param {number} n
 * @return {number}
 */
var climbStairs = function(n) {
 if(n < 2) {
 return 1;
 }
 let dp0 = 1;
 let dp1 = 1;
 for(let i= 2; i <= n; i++){
 let temp = dp0;
 dp0 = dp1;
 dp1 = dp0 + temp;
 }
 return dp1;
};
var climbStairs2 = function(n) {
 if(n < 2) {
 return 1;
 }
 let dp = [1, 1];
 for(let i= 2; i <= n; i++){
 dp[i] = dp[i-1] + dp[i-2];
 }
 return dp[n];
};

応用2:ハウスブレーキング

問題解決のアイデア

  • f(k) = 最初のk部屋から盗める最大額
  • Ak=k番目の家の資金数
  • f(k) = max(f(k-2) + Ak, f(k-1))
/**
 * @param {number[]} nums
 * @return {number}
 */
var rob = function(nums) {
 if(nums.length == 1){
 return nums[0];
 }
 if(nums.length == 0){
 return 0;
 }
 let dp0 = 0;
 let dp1= nums[0];
 for(let i=2; i <= nums.length; i++){
 const dp2 = Math.max(dp0 + nums[i-1], dp1);
 dp0 = dp1;
 dp1 = dp2;
 }
 return dp1;
};
var rob2 = function(nums) {
 if(nums.length == 1){
 return nums[0];
 }
 if(nums.length == 0){
 return 0;
 }
 let dp = [0, nums[0]];
 for(let i=2; i <= nums.length; i++){
 dp[i] = Math.max(dp[i-2]+ nums[i-1], dp[i-1]);
 }
 return dp[nums.length];
};

リングハウス213

/**
 * @param {number[]} nums
 * @return {number}
 */
var rob = function(nums) {
 if(nums.length == 0){
 return 0;
 }
 if(nums.length == 1){
 return nums[0];
 }
 //最後の家を盗まない
 let res1 = rawRob(nums.slice(0, nums.length - 1));
 let res2 = rawRob(nums.slice(1));
 return Math.max(res1, res2);
};
function rawRob(nums){
 let dp0 = 0;
 let dp1 = nums[0];
 for(let i = 2; i <= nums.length; i++){
 const dp2 = Math.max(dp0 + nums[i-1], dp1);
 dp0 = dp1;
 dp1 = dp2;
 }
 return dp1;
}

知識ソース:

Read next

あなたは本当にVueの計算を理解している?

次のようなコードがあるとします。renderメソッドのパラメータcは頻繁に変化しますが、aとbは頻繁に変化しません。このコードを分析すると、render関数が呼び出されるたびにcalc関数が呼び出され、aパラメータとbパラメータが変更されない場合、不要な計算が追加されると結論づけることができます。 この問題を解決する方法はたくさんあります。

Jun 23, 2020 · 8 min read