LeetCodeの動的計画法および関連する演習の問題解決方法(1)

注:文字通りの意味を探すのではなく、動的計画法の名前を使用してアルゴリズムを逆にしてください!実際、動的計画法は、高校のシリーズの質問のアップグレード版のようなものです。


動的計画法で解決できる問題について満たす必要のある2つのポイント

  1. 大きな問題を小さな問題に分解する
  2. マイナーな問題は繰り返し呼び出されます

動的計画法を適用する-動的計画法を3つのサブゴールに分割する

1.状態遷移方程式を確立します。

考え:f(1)〜f(n-1)の値を知り、それらを使用してf(n)を見つける方法を見つけます。

2.過去の結果をキャッシュして再利用します

適切な処理がないと、時間の複雑さは指数関数的になる可能性があります

3.小さいものから大きいものの順に計算します


例:

1.フィボナッチ数列(単純)

フィボナッチ数列:0、1、1、2、3、5、8、13、21、34、55、89、144、233 ...
この規則に従います。現在の値は、前の2つの値の合計です。では、n番目の値は何ですか?

まず、状態遷移方程式を簡単に取得できます。f(n)= f(n − 1)+ f(n − 2)、n> = 2 f(n)= f(n-1)+ f(n- 2)、n> = 2f n =f n1 +f n2 n>>=2

1.単純な再帰(反例):

def fib(n):
	if n < 2:
		return n
	else:
		return fib(n-1) + fib(n-2)
		
print(fib(100))

時間計算量インデックスレベル、書き込み効果なしと同じ
ここに画像の説明を挿入
2.動的計画法

def fib(n):
    result = list(range(n+1)) # 缓存以往的结果,方便复用(目标2)
    
    for i in range(n+1):      # 按顺序从小往大算(目标3)
        if i < 2:
            result[i] = i
        else:
            # 使用状态转移方程(目标1),同时复用以往结果(目标2)
            result[i] = result[i-1] + result[i-2] 
    
    return result[-1]

if __name__ == "__main__":
    result = fib(100)
    print(result)

ここに画像の説明を挿入


2.異なるパス(難易度)

リッチLeetCode—62。さまざまなパス

class Solution():
    def uniquePaths(self, m, n):   # 将二维列表初始化为1,以便之后用于缓存(目标2)
        dp = [[1]*n]*m

        for i in range(1, m):      # 外循环逐行计算(目标3)
            for j in range(1, n):  # 内循环逐行计算(目标3)
                dp[i][j] = dp[i][j-1] + dp[i-1][j]  # 状态方程(目标1),以及中间结果复用(目标2)

        return dp[m-1][n-1]

s = Solution()
m = 3
n = 2
print(s.uniquePaths(m, n))

昇華記事:

LeetCodeの動的計画法および関連する演習の問題解決方法(2)

おすすめ

転載: blog.csdn.net/weixin_43283397/article/details/108264137