初识动态规划(一)简单入门动态规划与上手操作
dp動態規劃
一、認識動態規劃
前言:近期我在慢慢刷動態規劃的題,雖然還是入門階段,但還是準備記錄我動態規劃前期是如何刷題過程
先根據一個例題來引入動態規劃——換零錢
提出問題:要求使用1,5,11的鈔票面額進行換總金額為w的最小張數
分析問題:在兌換的最終情況下(即換一最后一張面額的情況),要么是面額為1,要么5,要么11,所以
我們可以得出:(f(w)表示換w金額需要的最少張數)
- f(w) = f(w - 1) + 1; //該式子表示的是如果要得出f(w),就用前面已得出的f(w - 1) 加上一張面額為1的鈔票即可
- f(w) = f(w - 5) + 1;//該式子表示的是如果要得出f(w),就用前面已得出的f(w - 5) 加上一張面額為5的鈔票即可
- f(w) = f(w - 11) + 1;
故我們可知,若是求最少換零錢的張數就是
? f(w - 1) & f(w - 5) & f(w - 11)
? 三個中最小的那一個
? 3. 給出具體例子
那么,假如w=15的時候,同樣,鈔票面額分別為1,5,11,我們該取那種鈔票呢?當然是各種方案中,cost值最低的那一個!- 取1:cost = f(14) + 1 = 4 + 1 = 5;- 取5:cost = f(10) + 1 = 2 + 1 = 3;- 取11:cost = f(4) + 1 = 4 + 1 = 5;再次深度解釋一下:其中第二個取5的式子:f(10) = f(10 - 5) + 1 = 1 + 1; 即子問題的解;第三個取11的式子:f(4) = f(4 - 1) + 1 = 4;得出結論
大致我們可以得出,我們所求的就是前面 當前最優值 = 前面最優值 + 1
我們將求解f(w)就可以理解為求解多個子問題來達到求解f(w)
這就是dp --> 動態規劃
解決問題的特點
能將大問題拆成幾個小問題,且滿足無后效性(即不管前面的過程,只需要得出前面的子最優解解即可)
最優子結構性質,能夠由子問題推導出結果
詳細來說:
- 求最大最小值
- 從左上角走到右下角路徑的最大數字和
- 最長上升子序列
- 最長等差序列
- 最少換錢張數
- 計數
- 有多少種方式走到右下角
- 有多少種方法選出k個數使得和是sum
- 爬樓梯
- 判斷
- 是否存在先手贏,取石子游戲
解題一般步驟
二、下面進行具體刷動規的題型
-
斐波那契數
-
零錢兌換
-
最長遞增子序列
-
爬樓梯
斐波那契數
斐波那契數 (通常用 F(n) 表示)形成的序列稱為 斐波那契數列 。該數列由 0 和 1 開始,后面的每一項數字都是前面兩項數字的和。也就是:
F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
給定 n ,請計算 F(n) 。
示例 1:
輸入:n = 2
輸出:1
解釋:F(2) = F(1) + F(0) = 1 + 0 = 1
示例 2:
輸入:n = 3
輸出:2
解釋:F(3) = F(2) + F(1) = 1 + 1 = 2
示例 3:
輸入:n = 4
輸出:3
解釋:F(4) = F(3) + F(2) = 2 + 1 = 3
來源:力扣(LeetCode)
鏈接:https://leetcode.cn/problems/fibonacci-number
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
零錢兌換
給你一個整數數組 coins ,表示不同面額的硬幣;以及一個整數 amount ,表示總金額。
計算并返回可以湊成總金額所需的 最少的硬幣個數 。如果沒有任何一種硬幣組合能組成總金額,返回 -1 。
你可以認為每種硬幣的數量是無限的。
示例 1:
輸入:coins = [1, 2, 5], amount = 11
輸出:3
解釋:11 = 5 + 5 + 1
示例 2:
輸入:coins = [2], amount = 3
輸出:-1
示例 3:
輸入:coins = [1], amount = 0
輸出:0
來源:力扣(LeetCode)
鏈接:https://leetcode.cn/problems/coin-change
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
最長遞增子序列
給你一個整數數組 nums ,找到其中最長嚴格遞增子序列的長度。
子序列 是由數組派生而來的序列,刪除(或不刪除)數組中的元素而不改變其余元素的順序。例如,[3,6,2,7] 是數組 [0,3,1,6,2,2,7] 的子序列。
示例 1:
輸入:nums = [10,9,2,5,3,7,101,18]
輸出:4
解釋:最長遞增子序列是 [2,3,7,101],因此長度為 4 。
示例 2:
輸入:nums = [0,1,0,3,2,3]
輸出:4
示例 3:
輸入:nums = [7,7,7,7,7,7,7]
輸出:1
來源:力扣(LeetCode)
鏈接:https://leetcode.cn/problems/longest-increasing-subsequence
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
爬樓梯
假設你正在爬樓梯。需要 n 階你才能到達樓頂。
每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢?
示例 1:
輸入:n = 2
輸出:2
解釋:有兩種方法可以爬到樓頂。
示例 2:
輸入:n = 3
輸出:3
解釋:有三種方法可以爬到樓頂。
來源:力扣(LeetCode)
鏈接:https://leetcode.cn/problems/climbing-stairs
著作權歸領扣網絡所有。商業轉載請聯系官方授權,非商業轉載請注明出處。
總結:看完這幾道例題,大家也許會發現主要還是dp一維數組,并且算是比較簡單的,但是對于剛開始入門動規的話,應該能夠起到一定的作用,力扣上面也有一個動態規劃計劃集,我暫時也是根據上面做的。大家有興趣可以去跟著做一做。如有不足,請與我聯系更改。
我把鏈接放在這里,大家有興趣可以試試:力扣-動態規劃入門
總結
以上是生活随笔為你收集整理的初识动态规划(一)简单入门动态规划与上手操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue-element-template
- 下一篇: 动态规划C++实现--换钱的方法数(二)