国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

從斐波那契數(shù)列和零一背包問(wèn)題探究動(dòng)態(tài)規(guī)劃

開(kāi)發(fā) 前端
本人看了vivo,阿里巴巴的校招算法題,可以明確知道絕對(duì)有動(dòng)態(tài)規(guī)劃。如果沒(méi)有,那么出題的面試官真的沒(méi)有水平。跌了N次的動(dòng)態(tài)規(guī)劃,Runsen最近也拼命搞動(dòng)態(tài)規(guī)劃。這篇文章浪費(fèi)了三天時(shí)間。

[[387482]]

 本人看了vivo,阿里巴巴的校招算法題,可以明確知道絕對(duì)有動(dòng)態(tài)規(guī)劃。如果沒(méi)有,那么出題的面試官真的沒(méi)有水平。跌了N次的動(dòng)態(tài)規(guī)劃,Runsen最近也拼命搞動(dòng)態(tài)規(guī)劃。這篇文章浪費(fèi)了三天時(shí)間。

看了Leetcode公眾號(hào)的文章:https://mp.weixin.qq.com/s/rhyUb7d8IL8UW1IosoE34g

極客時(shí)間超哥的動(dòng)態(tài)規(guī)劃、拉勾教育的算法專欄。Runsen真的不想在動(dòng)態(tài)規(guī)劃,死一次又一次。死了N次,學(xué)了N次,就是他媽的寫(xiě)不出來(lái)。

動(dòng)態(tài)規(guī)劃需要搞定三個(gè)系列:三個(gè)背包,零錢(qián)問(wèn)題和股票問(wèn)題。今天,Runsen就開(kāi)始干掉最重要的「背包問(wèn)題」。

三個(gè)背包問(wèn)題:01背包,多重背包,完全背包。

動(dòng)態(tài)規(guī)劃前置知識(shí)

動(dòng)態(tài)規(guī)劃的名詞

「狀態(tài)轉(zhuǎn)移方程」:比如Runsen們一般看到的狀態(tài)轉(zhuǎn)移方程:dp[n] = dp[n-1] + dp[n-2]。

「最優(yōu)子結(jié)構(gòu):一般由最優(yōu)子結(jié)構(gòu),推導(dǎo)出一個(gè)狀態(tài)轉(zhuǎn)移方程 f(n),就能很快寫(xiě)出問(wèn)題的遞歸實(shí)現(xiàn)方法。把大問(wèn)題變成幾個(gè)小問(wèn)題,在幾個(gè)小問(wèn)題中求出最佳解?!?/p>

「重疊子問(wèn)題:比如斐波那契數(shù)列中的f(5),算了f(4)和f(3),結(jié)果f(4)又給Runsen算了一次f(3)。其實(shí)就是將一棵二叉樹(shù)進(jìn)行剪枝操作,方法是備忘錄來(lái)存儲(chǔ)在內(nèi)存上?!?/p>

「自下而上:反過(guò)來(lái)求解」

動(dòng)態(tài)規(guī)劃思路

動(dòng)態(tài)規(guī)劃是一種求問(wèn)題最優(yōu)解的方法。通用的思路:將問(wèn)題的解轉(zhuǎn)化成==> 求解子問(wèn)題,==> 遞推,==>最小子問(wèn)題為可直接獲得的初始狀態(tài)。

詳細(xì)的步驟下面所示:

判斷是否可用遞歸來(lái)解,可以的話進(jìn)入步驟 2

分析在遞歸的過(guò)程中是否存在大量的重復(fù)子問(wèn)題

采用備忘錄的方式來(lái)存子問(wèn)題的解以避免大量的重復(fù)計(jì)算(剪枝)

改用自底向上的方式來(lái)遞推,即動(dòng)態(tài)規(guī)劃

關(guān)鍵就是「找狀態(tài)轉(zhuǎn)移方程」。

斐波那契數(shù)列和爬樓梯問(wèn)題

斐波那契數(shù)列最早從兔子問(wèn)題演變過(guò)來(lái)的,

假設(shè)一對(duì)初生兔子一個(gè)月到成熟期,一對(duì)成熟兔子每月生一對(duì)兔子,并且一年內(nèi)沒(méi)有發(fā)生死亡。那么,由一對(duì)初生兔子開(kāi)始 一年以后可以繁殖多少對(duì)兔子?

我們直接看下面的圖


1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233……

發(fā)現(xiàn)以上規(guī)律是,每月的兔子對(duì)數(shù)=上一月的兔子對(duì)數(shù)+該月新生的兔子對(duì)數(shù)=上一月的兔子對(duì)數(shù)+上上月的兔子對(duì)數(shù)

得到序列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233……

這個(gè)序列即為斐波那契數(shù)列“(Fibonacci sequence)”。斐波那契數(shù)列中的任一個(gè)數(shù),都叫斐波那契數(shù)

斐波那契數(shù)列,通常都是用來(lái)講解遞歸函數(shù),嘗試用遞歸的思路來(lái)解決,但是時(shí)間復(fù)雜度高達(dá)。

  1. def fib(n): 
  2.   if n <= 1: 
  3.       return 1 
  4.   return fib(n-1) + fib(n-2) 
  5.  
  6. for i in range(20): 
  7.     print(fib(i), end=' '

但是,我們發(fā)現(xiàn)時(shí)間復(fù)雜度高達(dá),最主要的原因是存在重復(fù)計(jì)算。比如fib(3) 會(huì)計(jì)算 fib(2) + fib(1), 而 fib(2) 又會(huì)計(jì)算 fib(1) + fib(0)。

這個(gè) fib(1) 就是完全重復(fù)的計(jì)算,不應(yīng)該為它再遞歸調(diào)用一次,而是應(yīng)該在第一次求解除它了以后,就把他“記憶”下來(lái)。

這就是備忘錄解法,用空間來(lái)?yè)Q取時(shí)間的思路。把已經(jīng)求得的解放在字典Map或者列表list 里,下次直接取,而不去重復(fù)結(jié)算。

備忘錄解法的代碼和動(dòng)態(tài)規(guī)劃的代碼和思路基本一致。

斐波那契數(shù)列在Leetcode也有一題類似的,這是Leetcode第70題. 爬樓梯,每次你可以爬 1 或 2 個(gè)臺(tái)階。你有多少種不同的方法可以爬到樓頂呢?

注意:給定 n 是一個(gè)正整數(shù)。

  1. 輸入:2 
  2. 輸出:2 
  3. 解釋: 有兩種方法可以爬到樓頂。 
  4. 1.  1 階 + 1 階 
  5. 2.  2 階 

斐波那契數(shù)列和爬樓梯問(wèn)題的狀態(tài)轉(zhuǎn)移方程都是:dp[i] = dp[i-1] +dp[i-2]。但是需要初始化dp,不然回報(bào)list assignment index out of range的錯(cuò)誤。


下面就是斐波那契數(shù)列問(wèn)題 爬樓梯的解決代碼,也是Leetcode70題的解決代碼。

  1. class Solution: 
  2.     def Fibonacci(self, n): 
  3.         if n == 0: 
  4.             return 1 
  5.         if n == 1: 
  6.             return 1 
  7.         if n > 1: 
  8.             dp = [0] * (n+1) 
  9.             dp[0] = 1  
  10.             dp[1]= 1 
  11.             for i in range(2,n+1): 
  12.                 dp[i] = dp[i-1] +dp[i-2] 
  13.             return dp[n] 

Leetcode53 最大子序和

最大子序和,Runsen記得很清楚是Leetcode的53題。

  1. 輸入: [-2,1,-3,4,-1,2,1,-5,4], 
  2. 輸出: 6 
  3. 解釋: 連續(xù)子數(shù)組 [4,-1,2,1] 的和最大,為 6。 

聲明兩個(gè)變量, currentSum: 之前連續(xù)幾個(gè)值相加的和, maxSum: 當(dāng)前最大的子序列和。最大子序和狀態(tài)轉(zhuǎn)移方程 f(i) = max(f(i), f(i)+nums[i+1])

  1. def maxSubArray(nums) : 
  2.     '''查找連續(xù)子數(shù)組的最大和 
  3.  
  4.     Args: 
  5.         nums: 整數(shù)數(shù)組 
  6.  
  7.     Returns
  8.         返回整數(shù)數(shù)組的最大子序和 
  9.     ''
  10.     # 比較當(dāng)前子序和,最大子序和,返回最大值 
  11.  
  12.     # 定義當(dāng)前子序和以及最大子序和為第一個(gè)元素 
  13.     cursum = maxsum = nums[0] 
  14.     for i in range(1, len(nums)): 
  15.         cursum = max(nums[i], cursum + nums[i]) 
  16.         print(cursum) 
  17.         # 比較當(dāng)前值和定義的最大子序和值,將最大值重置賦值給 max_sum 
  18.         maxsum = max(cursum, maxsum) 
  19.         print(maxsum) 
  20.     return maxsum 
  21.  
  22. print(maxSubArray([-2,1,-3,4,-1,2,1,-5,4])) 

前面只是動(dòng)態(tài)規(guī)劃的熱身,Runsen先進(jìn)入「三個(gè)背包問(wèn)題的強(qiáng)化系列」,01背包問(wèn)題才是動(dòng)態(tài)規(guī)劃的入門(mén)階段。

01背包問(wèn)題

對(duì)應(yīng)的題目:https://www.acwing.com/problem/content/2/

01背包問(wèn)題就是物品只有一件。

  1. 輸入格式 : 第一行兩個(gè)整數(shù),N,V,用空格隔開(kāi),分別表示物品數(shù)量和背包容積。接下來(lái)有 N 行,每行兩個(gè)整數(shù) vi,wi,用空格隔開(kāi),分別表示第 i 件物品的體積和價(jià)值。  
  2. 輸出格式 : 輸出一個(gè)整數(shù),表示最大價(jià)值。  
  3. 數(shù)據(jù)范圍 : 0<N,V≤1000  ;0<vi,wi≤1000 

 輸入樣例

  1. 4 5 
  2. 1 2 
  3. 2 4 
  4. 3 4 
  5. 4 6 

輸出樣例:

  1. 8 # 4+4 2+6 

在解決這類問(wèn)題先,dp怎么定義和狀態(tài)轉(zhuǎn)移方程怎么搞就是重要,搞定了就是半分鐘的事情。搞不定了可能半小時(shí)的事情。

很多人和Runsen一樣,都會(huì)把狀態(tài)定義二維數(shù)組:為前i「?jìng)€(gè)」 物品中,體積恰好為v 時(shí)的最大價(jià)值。

狀態(tài)轉(zhuǎn)移方程也是順便搞定:

如果 「不選第 i 個(gè)物品」,那么前 i 個(gè)背包的最大價(jià)值就是前 i-1 個(gè)物品的價(jià)值,即 dp[i][j] = dp[i-1][j];

如果 「選擇了第 i 個(gè)物品」,前 i-1 個(gè)物品的體積就是j - weight[i],狀態(tài)方程為 dp[i - 1][j - weight[i]] + value[i],注意這時(shí)的價(jià)值是前i-1個(gè)物品的價(jià)值,因此少了 weight[i]]的空間,所以 dp[i - 1][j - weight[i]] + value[i]。

  1. ''
  2. @Author:Runsen 
  3. @WeChat:RunsenLiu  
  4. @微信公眾號(hào):Python之王 
  5. @CSDN:https://blog.csdn.net/weixin_44510615 
  6. @Github:https://github.com/MaoliRUNsen 
  7. @Date:2020/9/10 
  8. ''
  9. # n是個(gè)數(shù) v是體積  # 4 5 
  10. n, v = map(int, input().split()) 
  11. goods = [] 
  12. for i in range(n): 
  13.     goods.append([int(i) for i in input().split()]) 
  14.  
  15. # 初始化,先全部賦值為0,這樣至少體積為0或者不選任何物品的時(shí)候是滿足要求 
  16. # 因?yàn)?span id="5jnfyyd" class="keyword">for 循環(huán)先遍歷個(gè)數(shù),所以將體積寫(xiě)在里面 
  17. dp = [[0 for i in range(v+1)] for j in range(n+1)] 
  18. print(goods) # [[1, 2], [2, 3], [3, 4], [4, 5]] 
  19. # 0 可以無(wú)視掉 
  20. for i in range(1, n+1): 
  21.     for j in range(1,v+1): 
  22.         # 判斷背包容量是不是大于第i件物品的體積 
  23.         if j>=goods[i-1][0]: 
  24.             # 在選和不選的情況中選出最大值 
  25.             dp[i][j] = max(dp[i-1][j], dp[i - 1][j - goods[i - 1][0]] + goods[i - 1][1]) 
  26.         else
  27.             # 第i個(gè)物品不選 
  28.             dp[i][j] = dp[i-1][j]   
  29. print(dp) 
  30. print(dp[-1][-1]) 
  31.  
  32. # 測(cè)試數(shù)據(jù) 
  33. 5 10 
  34. 1 2 
  35. 2 3 
  36. 3 4 
  37. 4 5 
  38. 5 6 
  39. [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]] 
  40. [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [0, 2, 3, 5, 5, 5, 5, 5, 5, 5, 5], [0, 2, 3, 5, 6, 7, 9, 9, 9, 9, 9], [0, 2, 3, 5, 6, 7, 9, 10, 11, 12, 14], [0, 2, 3, 5, 6, 7, 9, 10, 11, 12, 14]] 
  41. 14  # 2+3+4+5 

上面代碼,如果知道了dp怎么定義和狀態(tài)轉(zhuǎn)移方程,那么和Runsen寫(xiě)的一樣快,其實(shí)那時(shí)Runsen寫(xiě)得挺慢得,說(shuō)不定你比Runsen還厲害。

上面的代碼是狀態(tài)定義二維數(shù)組,有的大佬竟然可以把狀態(tài)定義一維數(shù)組,這樣空間就節(jié)省了。「Runsen都百思不知其解」。只能說(shuō)Runsen真的挺菜的。只好勤能補(bǔ)拙!

一維數(shù)組就是去掉了狀態(tài),且的遍歷方式改為 「倒序」 遍歷到 c[i]。

因此,Runsen們可以將求解空間進(jìn)行優(yōu)化,將二維數(shù)組壓縮成一維數(shù)組,此時(shí),轉(zhuǎn)移方程變?yōu)椋?/p>

  1. ''
  2. @Author:Runsen 
  3. @WeChat:RunsenLiu  
  4. @微信公眾號(hào):Python之王 
  5. @CSDN:https://blog.csdn.net/weixin_44510615 
  6. @Github:https://github.com/MaoliRUNsen 
  7. @Date:2020/9/10 
  8. ''
  9. n, v = map(int, input().split()) 
  10. goods = [] 
  11. for i in range(n): 
  12.     goods.append([int(i) for i in input().split()]) 
  13. print(goods) # [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]] 
  14. dp = [0 for i in range(v + 1)] 
  15. for i in range(n): 
  16.     # 由于要放入物品,所以從空間v開(kāi)始遍歷到0 
  17.     for j in range(v, -1, -1): 
  18.         # 判斷背包容量是不是大于第i件物品的體積 
  19.         if j >= goods[i][0]: 
  20.             # 更新j的狀態(tài),即當(dāng)前容量放入物品之后的狀態(tài) 
  21.             dp[j] = max(dp[j], dp[j - goods[i][0]] + goods[i][1]) 
  22. print(dp) 
  23. print(dp[-1]) 
  24.  
  25. 5 10 
  26. 1 2 
  27. 2 3 
  28. 3 4 
  29. 4 5 
  30. 5 6 
  31. [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]] 
  32. [0, 2, 3, 5, 6, 7, 9, 10, 11, 12, 14] 
  33. 14 

上面就是01背包的最終解決方法,由于文章有限,多重背包,完全背包將在之后的博客進(jìn)行書(shū)寫(xiě)!!!

不知不覺(jué)現(xiàn)在寫(xiě)了幾天,代碼反復(fù)寫(xiě),寫(xiě)完寫(xiě)博客,真心累!誰(shuí)叫自己的算法比較弱!

希望以后遇到01背包的問(wèn)題,就是在恐怖的算法面試中遇見(jiàn)了Runsen的愛(ài)情!

參考資料

[1]傳送門(mén)~:https://github.com/MaoliRUNsen/runsenlearnpy100

 

責(zé)任編輯:姜華 來(lái)源: Python之王
相關(guān)推薦

2020-05-11 14:18:14

JavaScript斐波那契數(shù)列遞歸

2021-10-31 21:01:00

數(shù)列TypeScriptJava

2012-02-22 10:14:44

Java

2021-05-16 18:02:52

系統(tǒng)編程JavaScript

2021-12-28 07:20:44

斐波那契數(shù)算法數(shù)字

2023-06-13 06:51:15

斐波那契數(shù)算法

2021-10-22 08:22:37

線程Smt內(nèi)核

2021-05-08 08:28:38

Java數(shù)據(jù)結(jié)構(gòu)算法

2024-03-25 08:00:00

C++遞歸函數(shù)

2022-11-14 08:12:34

2021-03-17 08:37:23

算法性能分析遞歸算法遞歸樹(shù)

2021-04-13 07:58:38

背包代碼模式

2022-03-28 15:15:15

神經(jīng)網(wǎng)絡(luò)編程開(kāi)發(fā)

2013-04-10 10:58:19

LambdaC#

2020-04-20 11:09:18

Python開(kāi)發(fā)語(yǔ)言

2021-01-19 05:46:45

背包數(shù)組容量

2013-09-02 10:05:06

C編程語(yǔ)言

2022-06-27 19:19:26

算法題青蛙跳臺(tái)階

2012-02-22 14:12:08

算法

2021-02-09 09:55:24

動(dòng)態(tài)規(guī)劃
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

国产一区二区三区综合| 日本一区二区三区四区高清视频| 国产欧美日韩精品高清二区综合区| 7777精品久久久大香线蕉小说| 国产在线精品不卡| 猫咪av永久| 欧美日韩视频专区在线播放| 久久99国产精品二区高清软件| 国产精品一香蕉国产线看观看 | 成人精品视频.| 青青草手机在线| 最近的2019中文字幕免费一页| 999国产精品视频| 日日摸日日碰夜夜爽无码| 欧美综合亚洲图片综合区| 亚洲va欧美va人人爽成人影院| 欧美日韩国产一二| 一区二区三区日韩在线观看| 欧美舌奴丨vk视频| 精品不卡一区二区三区| 亚洲视频免费看| 成人a在线观看高清电影| 久久人人九九| 欧美精品aaaa| 日韩电影免费在线看| 激情小说激情视频| 亚洲欧美日韩高清| 欧美日本一区二区视频在线观看| 日韩人妻精品无码一区二区三区| 欧美一个色资源| 91蜜臀精品国产自偷在线| 成人羞羞国产免费网站| 精品免费一区二区三区| 91精品久久久久久久久久不卡| 欧美伦理片在线看| 亚洲午夜激情免费视频| 亚洲欧美日本日韩| 好男人免费精品视频| 欧美综合激情网| 2欧美一区二区三区在线观看视频| 中文字幕在线观看播放| 99精彩视频在线观看免费| 国产精品国模大尺度视频| 3d欧美精品动漫xxxx无尽| 久久精品日产第一区二区三区| 精品久久久久久久久久| 国产精品白浆| 日韩毛片在线免费看| 在线播放日韩精品| 国产麻豆精品95视频| av在线私库| 伊人狠狠色丁香综合尤物| 欧美男男青年gay1069videost| 国产精品99久久精品| 日韩欧美国产精品一区二区三区| 国产在线播精品第三| 一本一道久久a久久精品| 亚洲国产高清在线观看| 久久av高潮av| 亚洲第一综合天堂另类专| 激情婷婷欧美| 日本不卡免费播放| 国产精品爽爽爽爽爽爽在线观看| 日本一区二区三区免费乱视频 | 日韩精品一二三四| 日本中文字幕在线观看| av资源站久久亚洲| 欧美日韩亚洲精品一区二区三区 | 亚洲男人天堂2023| 国内一区二区在线| 欧美男女交配| 国产美女在线一区| 久久久国产一区| 91色综合久久久久婷婷| 欧美成年网站| 成人国产视频在线| 国产精品久久久久久久久久99| 亚洲精品国久久99热| 欧美xxav| 伊人免费在线| 一本一本a久久| 影音先锋欧美精品| 久久久国产午夜精品| 青青草久久爱| 日产精品久久久久久久性色| 久久影院理伦片| 亚洲欧美一区二区三区久久 | 久久综合狠狠综合| 日韩成人一级| 国产香蕉视频在线观看| 97在线电影| 欧美成人精品二区三区99精品| 激情六月婷婷久久| 成人在线日韩| 免费看成年人视频在线观看| 成人av男人的天堂| 国产视频精品自拍| 国产精品色哟哟网站| 综合激情一区| а√天堂中文在线资源8| 少妇高潮毛片色欲ava片| 国内精品免费午夜毛片| 高跟丝袜欧美一区| 久久丁香综合五月国产三级网站| 成人动漫视频在线观看| 五月伊人六月| 色爱区成人综合网| 色综合久久久久久中文网| 精品国产福利视频| 美国毛片一区二区三区| 亚洲欧洲二区| 色视频在线观看| 国产人妻互换一区二区| 欧美在线日韩在线| 日韩色在线观看| 国产人成一区二区三区影院| 欧美/亚洲一区| 欧美一级大黄| 一二三区在线观看| 精品人妻大屁股白浆无码| 国产精品久久久久久网站| 欧美大胆一级视频| 国产精品久久久久永久免费观看 | 欧美高清性猛交| 日韩欧美在线网址| 国产91精品免费| 久久亚洲国产| a欧美人片人妖| 天堂av中文在线资源库| 丁香婷婷综合激情| 亚洲aa中文字幕| 国产午夜精品视频| 欧美午夜片欧美片在线观看| jlzzjlzz国产精品久久| 在线观看的日韩av| 第四色中文综合网| 欧美xxxx视频| 美女的诞生在线观看高清免费完整版中文 | 久久全国免费视频| 欧美久久一二区| 国产亚洲欧美一区在线观看| 亚洲黄色高清| 久久影视三级福利片| 黄视频免费在线看| 一二三区在线| 国产精品第12页| 少妇特黄a一区二区三区| 国产精品嫩草视频| 中文字幕日韩在线播放| 欧美亚洲动漫另类| 综合精品久久久| 高清日韩电视剧大全免费| 亚洲免费激情| av中文字幕一区二区| 亚洲青青久久| ****av在线网毛片| 日本免费一区二区三区最新| 久久久久久久久久久久久久国产| 天堂精品视频| 国产乱码一区| 国产精品三级美女白浆呻吟| 久热精品视频在线免费观看| 精品国产1区二区| 欧美三级在线播放| 亚洲精品老司机| 26uuu亚洲婷婷狠狠天堂| 蜜臀久久久久久久| 在线高清一区| 亚洲午夜精品一区二区国产| 亚洲裸色大胆大尺寸艺术写真| 成人国产精品久久| 播放一区二区| bl视频在线免费观看| 98在线视频| 国产精品一二三区视频| 天天夜夜亚洲| 麻豆免费网站| 成人福利影院| 999www人成免费视频| 欧美午夜性生活| 老熟妇仑乱视频一区二区| 两根大肉大捧一进一出好爽视频| 警花观音坐莲激情销魂小说| 亚洲一区二区三区精品动漫| 日本精品一区二区三区高清 久久| 91成人理论电影| 国产主播欧美精品| 国产精品人人做人人爽| 青青在线视频一区二区三区| 午夜精品www| 久久频这里精品99香蕉| 久久久视频在线| 国产69精品久久久久9| 欧美精品xxx| 欧美一级淫片aaaaaaa视频| 欧美综合一区第一页| 91精品国产高清久久久久久久久| 91精品国产沙发| 国产成人精品免费视频| 国产精品免费网站|