1. 程式人生 > >《面試--動態規劃》 ---五種經典的演算法問題

《面試--動態規劃》 ---五種經典的演算法問題

一 動態規劃

動態規劃問題是面試題中的熱門話題,如果要求一個問題的最優解(通常是最大值或者最小值),而且該問題能夠分解成若干個子問題,並且小問題之間也存在重疊的子問題,則考慮採用動態規劃。

使用動態規劃特徵:
1. 求一個問題的最優解
2. 大問題可以分解為子問題,子問題還有重疊的更小的子問題
3. 整體問題最優解取決於子問題的最優解(狀態轉移方程)
4. 從上往下分析問題,從下往上解決問題
5. 討論底層的邊界問題

例項1
剪繩子問題
給你一根長度為N的繩子,請把繩子剪成M段(m,n都是整數),每段繩子的
長度記為k[0],k[1],k[2]…. 請問如何剪繩子使得k[0],k[1],k[2]
的乘積最大
例如 繩子長度8 最大乘積18 = 2*3*3

def jianshengzi(n):
    # 先對邊界問題進行求解,因為明顯剪的值小於不剪的值
    # 則提出先討論這三種情況
    if n < 2:
        return 0
    if n == 2:
        return 1    #長度為2,只能剪成1*1
    if n == 3:
        return 2    #長度為3,剪成2*1 > 1*1*1

    #若繩子長於4呢,申請一個長度為50的陣列
    #羅列出切割的邊界問題

    h = [0]*50
    h[0] = 0
    h[1] = 1
    h[2
] = 2 h[3] = 3 # 遞迴問題是 f(n) = max{f(i)*f(n-i)} for i in range(4,n+1): maxs = 0 for j in range(1,i/2+1): mult = h[j] * h[i-j] if maxs < mult: maxs = mult h[i] = maxs # 每次J的迭代輪詢出該長度的最大值 print h return h[n] print
jianshengzi(8)

例項2
硬幣問題
我們有面值為1元3元5元的硬幣若干枚,如何用最少的硬幣湊夠11元?
分析:
1 求問題的最優解:最小的硬幣數
2 是否有子問題:f(n)表示的最少硬幣數是是上一次拿時候的硬幣數最少。
注意:f(n)是n元的最小硬幣數,最後一次可拿的硬幣數為1,3,5 則下一步
的最小硬幣數為 f(n-vi) 它的狀態變更不是按元數的,是按照上次拿的硬幣錢目
3 狀態轉移方程為 f(n)= min(f(n-vi)+1)
4 邊界問題(找到最後一個重複的問題) 這裡
f(1)=1 ,f(2)=f(1)+f(1)=2 f(3)=min(1,f(2)+1)
f(4)=f(3)+1 f(5)=1
5 從上往下分析問題,從下往上解決問題。

def f(n):
    if n == 1:      #把所有的邊界問題找到
        return 1
    if n == 2:
        return 2
    if n == 3:
        return 1
    if n == 4:
        return 2
    if n == 5:
        return 1

    h = [1,3,5]
    minx = n
    for i in range(3):
        coun = f(n-h[i])+1    # 採用了遞迴的思想 這裡是從上到下,
        if minx > coun:       # 複雜度比較高
            minx = coun
    return minx

print f(11)
def f(n):
    if n == 1:
        return 1
    if n == 2:
        return 2
    if n == 3:
        return 1
    if n == 4:
        return 2
    if n == 5:
        return 1

    h = [1,3,5]
    for x in range(6,n+1):     #從下往上的思維解決
        minx = n
        for i in range(3):      
            coun = f(x-h[i])+1   #從下往上的思維解決 
            if minx > coun:
                minx = coun
    return minx
print f(11)

相關推薦

面試--動態規劃》 ---經典演算法問題

一 動態規劃 動態規劃問題是面試題中的熱門話題,如果要求一個問題的最優解(通常是最大值或者最小值),而且該問題能夠分解成若干個子問題,並且小問題之間也存在重疊的子問題,則考慮採用動態規劃。 使用動態規劃特徵: 1. 求一個問題的最優解 2. 大問題可以分

第四章作業-串-計算機17級 7-1 最長對稱子串 (25 分)四方法求解(暴力列舉+動態規劃+中心擴充套件+manacher演算法(馬拉車))

7-1 最長對稱子串 (25 分) 對給定的字串,本題要求你輸出最長對稱子串的長度。例如,給定Is PAT&TAP symmetric?,最長對稱子串為s PAT&TAP s,於是你應該輸出11。 輸入格式: 輸入在一行中給出長度不超過1000的非空字串

資料結構與演算法隨筆之------最長迴文子串四方法求解(暴力列舉+動態規劃+中心擴充套件+manacher演算法(馬拉車))

所謂迴文串,就是正著讀和倒著讀結果都一樣的迴文字串。 比如: a, aba, abccba都是迴文串, ab, abb, abca都不是迴文串。 一、暴力法 方法一:直接暴力列舉 求每一個子串時間複雜度O(N^2), 判斷子串是不是迴文O(N),兩者是相乘關係,所以時間

LeetCode 926. 將字串翻轉到單調遞增 遞迴實現動態規劃解法

這個題做了一個多小時,考慮複雜了。 開始推動規沒有推出來,然後找到一個遞推關係:從左往右,如果是0,則不需要變動;如果是1,則有兩種選擇(1)將1變為0(2)將1後面的所有數字變為1,這兩種方法中的變動數字最小的方法就是最佳方法,然後依次遞推,很容易寫出遞迴程式。但是這裡面存

排序演算法

一:插入排序 二:選擇排序 三:氣泡排序 四:歸併排序 五:快速排序   #include <iostream> #include<vector> #include<algorithm> #include<string>

動態規劃(DP)演算法

    動態規劃相信大家都知道,動態規劃演算法也是新手在剛接觸演算法設計時很苦惱的問題,有時候覺得難以理解,但是真正理解之後,就會覺得動態規劃其實並沒有想象中那麼難。網上也有很多關於講解動態規劃的文章,大多都是敘述概念,講解原理,讓人覺得晦澀難懂,即使一時

DAG上的動態規劃(紫書經典)

一、矩形巢狀問題 1.題目描述 2.程式碼實現 #include<iostream> #include<algorithm> #include<math.h> #include<string> #include

演算法課程實驗一】排序演算法的分析比較

實驗目的:掌握選擇排序、氣泡排序、合併排序、快速排序、歸併排序的演算法原理分析不同排序演算法的時間效率和時間複雜度,以及理論值與實測資料的對比分析。一、氣泡排序演算法虛擬碼:for i=1 to n      for j=0 to n-i

排序演算法的JAVA 實現

1.插入排序 函式程式碼如下: public void insertSort(int length){ int k = 0; for(int pres

8經典演算法之氣泡排序

氣泡排序(Bubble Sort),是一種電腦科學領域的較簡單的排序演算法。它重複地走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。走訪數列的工作是重複地進行直到沒有再需要交

最小生成樹的兩經典演算法--prim演算法和kruskal演算法

一個連通圖的生成樹是圖的一個極小連通子圖,它包含所有頂點,但只有足以構成樹的n-1條邊 這意味著對生成樹來說,砍去它的任何一條邊,就會使生成樹變成非連通圖,若給他增加一條邊就會形成一條迴路 最小生成樹:權值最小的那顆生成樹叫~ 最小生成樹的性質: 最小生成樹

從暴力求解到動態規劃—— 7 方法求解連續子陣列的最大和問題(python實現)

問題描述 已知一個數組 a[n],裡面存放著浮點數,可能是正數、負數或0。求它的所有連續子陣列中的最大和。 連續子陣列:指的是陣列的一個連續切片,即可以表示為 a[i:j],0≤i≤j<n。 連續子陣列的和:比如連續子陣列為 a[i:j] ,則和為

8經典演算法之選擇排序

選擇排序是一種簡單直觀的排序方法。 排序原理: 第一輪掃描找到最小的數放在最前面; 第二輪掃描找到第二小的數放在第二位; 依次類推。 使得整個序列為有序序列。 選擇排序圖解: 程式

ac之最小生成樹的兩經典演算法

傳送門佈線問題時間限制:1000 ms  |  記憶體限制:65535 KB難度:4描述南陽理工學院要進行用電線路改造,現在校長要求設計師設計出一種佈線方式,該佈線方式需要滿足以下條件:1、把所有的樓都供上電。2、所用電線花費最少輸入第一行是一個整數n表示有n組測試資料。(n

動態規劃——一個神奇的演算法

當我第一次做到一個題,那是一個擁暴搜來解決的問題。原本只是想要簡單的看一下貪心法的演算法實現,沒想到竟然挖出了真麼個龐然大物。 在沒有看到他的程式碼實現之前,我一直以為計算機只是一個可以大量快速計算,但卻只能以二進位制,傻傻的算的機器。我沒要做的,便是把一切問題轉化為二進位

面試常考8排序演算法的總結

(1)插入排序 直接插入排序是一種較簡單的排序方法; 演算法思想: 將一個記錄插入到已排好的有序表中,從而得到一個新的記錄數加一的有序表; 示例:{3,45,66,97,1,6,65} 初始關鍵字 :

構造迴文(動態規劃,遞迴演算法)

給定一個字串s,你可以從中刪除一些字元,使得剩下的串是一個迴文串。如何刪除才能使得迴文串最長呢? 輸出需要刪除的字元個數。 輸入資料有多組,每組包含一個字串s,且保證:1<=s.length<=1000. 對於每組資料,輸出一個整數,代表最少需要刪除的字元個數

nginx反向代理的負載演算法

在負載反向代理的演算法上,共有五種:輪詢、ip_hash、weight、fair(第三方)、url_hash(第三方) 輪詢是預設的,每一個請求按順序逐一分配到不同的後端伺服器,如果後端伺服器down掉了,則能自動剔除。(如果又存活了,能自動加進來嗎?)  

PHP常見演算法

氣泡排序: <?php /** * Created by PhpStorm. * User: maguanya * Date: 2018/1/9 * Time: 下午1:38 *

動態規劃思想分析——經典題目

動態規劃思想是演算法設計中很重要的一個思想,所謂動態規劃就是“邊走邊看”,前面的知道了,後面的根據前面的也就可以推出來了。和分治演算法相似又不同,相同的是都需要去尋找最優子結構,重複子問題,邊界條件。不同的是動態規劃演算法儲存前面算得的每一個結果,後面的結果由前面的結果推倒