動的計画法の古典的アルゴリズム(フィボナッチ数列)

該当するシーン:

サブ問題は元の問題と同じ性質のものです

サブ問題は相互に関連しています(分割統治アルゴリズムとは異なります)

最適なソリューションを求めて、コアは網羅的です

動的計画機能:

  1. 重複するサブ問題
  2. 状態遷移方程式(最も重要)
  3. 最適な下部構造

動的計画問題解決フレームワーク

  1. 規範事例
  2. 網羅的な状態
  3. 状態遷移

古典的なケース1:フィボナッチ数列

f [1] = 1
f [2] = 2
f [n] = f [n-1] + f [n-2] //状態遷移方程式

フィボナッチ数列は、本物の動的計画問題ではなく、少なくとも最適解を探す問題ではありません。

コードの実装-再帰(暴力的な再帰)

/*
    斐波那契数列
    暴力递归
*/
#include <stdio.h>
#include <stdlib.h>

int fib(int n) {
    // base_case
    if (n ==1 || n ==2) {
        return n;
    }
    // 递归调用
    return fib(n - 1) + fib(n - 2);
}

int main() {
    int n = 200;
    printf("fib(%d) = %d\n", n, fib(n));
    return 0;
} 

再帰法は非効率的です。繰り返し計算が多く、時間計算量はO(2 ^ n)であり、時間がかかります。

コードの実装-再帰的メソッド(トップダウン/メモ付き)

最初に上から下に再帰し、次に下から上に戻ります。

/*
    斐波那契数列
    带备忘录的递归
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int helper(int *memo, int n) {
    // base_case
    if (n ==1 || n ==2) {
        return n;
    }
    // 备忘录查询
    if (memo[n] != 0) return memo[n];

    memo[n] = helper(memo, n - 1) + helper(memo, n - 2);
    return memo[n];
}

int fib(int n) {
    // 备忘录初始化
    int *memo = new int[n + 1];
    memset(memo, 0, n+1);
    // 进行带备忘录的递归
    return helper(memo, n);
}

int main() {
    int n = 50;
    printf("fib(%d) = %d\n", n, fib(n));
    return 0;
} 

現在、すべてのノードは1回だけ計算されるため、時間計算量はO(n)です。
追加の新しいメモリ割り当てのため。したがって、スペースの費用がもう1つあるため、スペースの複雑さはO(n)になります。
メモ付きの再帰的解決策は時間の空間です

コードの実装-反復法(ボトムアップ)

/*
    斐波那契数列
    带备忘录的递归
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int helper(int *memo, int n) {
    // base_case
    if (n ==1 || n ==2) {
        return n;
    }
    // 备忘录查询
    if (memo[n] != 0) return memo[n];

    memo[n] = helper(memo, n - 1) + helper(memo, n - 2);
    return memo[n];
}

int fib(int n) {
    // 备忘录初始化
    int *memo = new int[n + 1];
    memset(memo, 0, n+1);
    // 进行带备忘录的递归
    return helper(memo, n);
}

int main() {
    int n = 50;
    printf("fib(%d) = %d\n", n, fib(n));
    return 0;
} 

 

おすすめ

転載: blog.csdn.net/weixin_44937328/article/details/115344896
おすすめ