成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如何掌握動態規劃算法的套路?

開發 前端 算法
動態規劃(Dynamic Programming),簡稱DP,這個名字給人的感覺是一種非常高大上非常復雜的算法,很多同學看到這個名字可能就會望而卻步,在面試的時候也非常害怕被問到動態規劃的題目。

[[358211]]

動態規劃(Dynamic Programming),簡稱DP,這個名字給人的感覺是一種非常高大上非常復雜的算法,很多同學看到這個名字可能就會望而卻步,在面試的時候也非常害怕被問到動態規劃的題目。實際上,它并不是不是一種確定的算法,它是一種最優化的方法求解問題的思想或方法。它是由美國數學家貝爾曼(Bellman)在研究多階段決策過程的優化問題時提出。不過,與之對應的還有一些與時間無關的靜態規劃,如:線性規劃、非線性規劃等。在運籌學中,動態規劃是的非常重要的內容,在各個行業領域都有著廣泛的應用。我們如何理解動態規劃?

如果一個問題的最優解可以通過其子問題的最優解經過推導得到,那么,我們就可以先求出其子問題的最優解,根據子問題的解得出原問題的最優解。如果子問題有較多的重復出現,為了減少重復計算,降低時間復雜度,則可以自底向上從最終子問題向原問題逐步求解并先將子問題存儲起來,在求解大的子問題時可以直接從表中查詢子問題的解,這就是動態規劃的基本思想。

簡單來來理解就是將一個大問題簡化成若干子問題,并存入一個表中,再根據數據表中子問題的解求出大問題的解。這種算法看上去是不是很熟悉?其實,動態規劃和分治算法類似,我們也常常將其和分治算法進行比較。它們都需要將其分解成若干子問題并求解子問題。不同的是分治算法是自頂向下求解各子問題,然后合并子問題的解從而得到原問題的解;而動態規劃是將子問題拆解之后,自底向上求解子問題的解并將存儲結果存儲起來,在求解大的子問題時直接查詢子問題的解,算法效率也將大大的提高。

理論描述太過生硬和枯燥,我們直接來看一個例子。

斐波那契數列

斐波那契數列

斐波那契數列是一個非常神奇的數列,它由意大利數學家萊昂納-斐波那契提出,其特征是數列某一項的值是前兩項的和,也可以稱作黃金分割數列。

[[358213]]

萊昂納多·斐波那契

我們可以用下面的通項公式來表示斐波那契數列。

從斐波那契數列的公式中可知,數列的第n(n>2)項的值f(n)等于f(n)+f(n-1),如果要求得f(n)值就需要先求得f(n-1)和f(n-2)的值,為了便于分析,我們當假設n=6,我們可以按照下圖進行分解,一步步分解成小的值。

斐波那契

看了上面的圖,想必大家腦海中一種想到了程序的實現,我們可以直接通過遞歸的方法就可以求出n項的值,程序很容易,如下所示。

  1. int fib(int n) 
  2.     if(n==1 || n==2) return 1; 
  3.     return fib(n-1) + fib(n-2); 

但是,很明顯這種算法是指數時間復雜度O(2^n),其復雜度會隨著n的增加成指數增長,當n取到一定大時,將需要很長的時間,顯然這不是一種最優的算法。不過,仔細觀察上圖的各個分解項,我們會發現圖中有很多重復的子項,這就是上面這種遞歸算法復雜度較高的原因。那么,還能不能進行優化呢?答案是肯定的。

我們可以通過動態規劃的思想來優化上面這個算法,為了避免大量的重復計算,我們可以從最底層的子問題開始計算,并通過一個表來存儲這些子問題的值,當再次遇到這個值就不需要再重新計算。

如下面的程序,我們從最小的子問題n=1,2開始向上計算,并且定義了一個vector容器用來存儲被計算過的子問題的值,下次再計算大問題時直接調用容器里的值即可。

  1. int fib(int n) 
  2.     vector<int> dp(n, 0); 
  3.  
  4.     dp[0] = dp[1] = 1; 
  5.     for (int i = 2; i < n; i++) 
  6.     { 
  7.         dp[i] = dp[i - 1] + dp[i - 2]; 
  8.     } 
  9.  
  10.     return dp[n-1]; 

很明顯上面的這種算法,大大降低了算法的時間復雜度,現在的時間復雜度就是O(n)了。不過,雖然時間復雜度降低了,這卻是犧牲了空間換取過來的。實際上我們還可以進一步去優化,從公式上我們分析可以看出,要求出某一項的值我們需要先求出其前兩項子問題的值,當我們自下而上求解子問題的過程中,我們直接保存連續兩項子問題的值即可。

  1. int fib(int n) 
  2.     int dp[2]={1,1}; 
  3.  
  4.     for (int i = 2; i < n; i++) 
  5.     { 
  6.         int tmp = dp[0]; 
  7.         dp[0] = dp[1]; 
  8.         dp[1] = dp[1] + tmp; 
  9.     } 
  10.  
  11.     return dp[1]; 

最長上升子序列

嚴格意義上來說,上面的斐波那契數列也不完全算是動態規劃問題。因為從動態規劃的定義上來看,動態規劃問題一般滿足三個性質:

  • 最優化原理:如果原問題的最優解所分解出的子問題的解也是最優的,我們就稱該問題具有最優子結構,原問題的最優解可以由子問題的最優解推導得出;
  • 無后效性:某階段狀態一旦確定,這個狀態以后決策的影響,它只與當前狀態有關;
  • 有重疊子問題:子問題可能會在下一階段決策中被重復多次用到。

根據動態規劃問題的這三個性質我們再看另外一個例子,最長上升子序列(Longest Increasing Subsequence)問題,簡稱LIS,這是一個非常經典的動態規劃問題。

有一個長度為n的數列a0, a1, ..., a(n-1),求出這個序列中最長的上升子序列的長度。所謂上升子序列指的是對于任意的i

我們先將原問題進行分解,依次拆解成子問題,如下表:

子序列

我們的代碼可以按照下面來實現,其中,程序里我們用dp數組保存各個子序列以nums[i]結尾的最長子序列長度,max存儲最長子序列的長度。

  1. int maxLIS(std::vector<int>& nums) 
  2.     int max = 1; 
  3.     std::vector<int> dp(nums.size(), 1); 
  4.  
  5.     for(int i = 1;i< nums.size(); i++) 
  6.     { 
  7.         for(int j=0; j<i; j++) 
  8.         { 
  9.             if(nums[i]>nums[j]) 
  10.             { 
  11.                 dp[i] = dp[j] + 1; 
  12.             } 
  13.             max = std::max(dp[i], max); 
  14.         } 
  15.     } 
  16.  
  17.     return max

通過上面的兩個例子,大家都學廢了嗎?常見的還有很多問題可以使用動態規劃的方法解決,比如,背包問題,硬幣找零,最短路徑等。動態規劃不是一種固定的算法,對應的問題也是多種多樣,但大家只要掌握了其基本的思想,就可以輕松的解出相應的問題,大家趕快去嘗試一下吧!

本文轉載自微信公眾號「Will的大食堂」,可以通過以下二維碼關注。轉載本文請聯系Will的大食堂公眾號。

 

責任編輯:武曉燕 來源: Will的大食堂
相關推薦

2021-05-13 07:34:56

Java數據結構算法

2020-07-07 08:02:33

動態規劃緩存枚舉

2020-12-02 09:36:20

算法分支思想

2023-10-11 10:13:45

自動駕駛軌跡

2017-09-27 14:46:37

Vue2.xDOM diff原理

2022-05-12 09:00:50

動態規劃算法項目

2024-01-05 09:23:09

Linux系統內存內存指標

2016-09-18 15:38:10

CMDB配置

2011-11-09 09:53:40

算法

2024-07-01 10:22:00

2010-05-24 14:38:41

MySQL數據庫

2024-07-11 11:40:18

2023-06-13 06:51:15

斐波那契數算法

2010-07-08 13:00:30

動態路由協議

2023-10-23 08:12:34

并發問題有鎖和無鎖

2021-12-27 11:30:51

數據結構算法動態規劃

2021-08-11 07:22:27

Vue 技巧 開發工具

2010-09-01 16:38:52

無線網絡射頻信號

2021-10-28 18:58:57

動態規劃數據結構算法

2022-12-29 08:12:51

動態規劃profit
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲视频中文字幕 | 欧美一区二区三区大片 | 毛片免费视频 | 国产精品激情小视频 | 欧美黄色精品 | 久久国产日本 | 欧美一级高潮片免费的 | 国产99久久精品一区二区永久免费 | 麻豆亚洲 | 日本精a在线观看 | 91在线视频播放 | 就操在线 | 亚洲一区二区三区四区五区午夜 | 夜夜操天天艹 | a级黄色网 | 欧美精品二区 | 亚洲欧美一区二区三区情侣bbw | 国产一级片免费在线观看 | 国产精品日韩在线 | 黄色a视频 | 做a网站 | 亚洲精品av在线 | 欧美日批 | 涩爱av一区二区三区 | 亚洲欧美在线观看 | 夜夜久久| 国产一区2区| 欧美在线一区二区三区 | www.亚洲国产精品 | 看片国产 | 国产精品99久 | 欧美一级黄色片免费观看 | 一区二区三区国产精品 | 精品福利在线 | 欧美视频第二页 | 成人日批视频 | 麻豆精品一区二区三区在线观看 | 成人免费精品视频 | 特级黄一级播放 | 久久久久久久91 | 午夜国产一级 |