C 程式設計之經典演算法 遞迴過程(四)

2021-05-26 03:05:38 字數 963 閱讀 5135

揹包問題(knapsack problem)

揹包問題是一種組合優化的np完全問題

。問題可以描述為:給定一組物品,每種物品都有自己的重量和**,在限定的總重量內,我們如何選擇,才能使得物品的總**最高。問題的名稱**於如何選擇最合適的物品放置於給定揹包中。相似問題經常出現在商業、組合數學,計算複雜性理論

、密碼學和應用數學等領域中。也可以將揹包問題描述為決定性問題,即在總重量不超過w的前提下,總價值是否能達到v?它是在2023年由merkel和hellman提出的。

有n件物品和乙個容量為v的揹包。第i件物品的重量是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的重量總和不超過揹包容量,且價值總和最大。

這是最基礎的揹包問題,特點是:每種物品僅有一件,可以選擇放或不放。

用子問題定義狀態:即f[i][v]表示前i件物品恰放入乙個容量為v的揹包可以獲得的最大價值。則其狀態轉移方程便是:f[i][v]=max 。 可以壓縮空間,f[v]=max

這個方程非常重要,基本上所有跟揹包相關的問題的方程都是由它衍生出來的。所以有必要將它詳細解釋一下:「將前i件物品放入容量為v的揹包中」這個子問題,若只考慮第i件物品的策略(放或不放),那麼就可以轉化為乙個只牽扯前i-1件物品的問題。如果不放第i件物品,那麼問題就轉化為「前i-1件物品放入容量為v的揹包中」,價值為f[i-1][v];如果放第i件物品,那麼問題就轉化為「前i-1件物品放入剩下的容量為v-c[i]的揹包中」,此時能獲得的最大價值就是f [i-1][v-c[i]]再加上通過放入第i件物品獲得的價值w[i]。

注意f[v]有意義當且僅當存在乙個前i件物品的子集,其費用總和為v。所以按照這個方程遞推完畢後,最終的答案並不一定是f[n] [v],而是f[n][0..v]的最大值。如果將狀態的定義中的「恰」字去掉,在轉移方程中就要再加入一項f[v-1],這樣就可以保證f[n] [v]就是最後的答案。至於為什麼這樣就可以,由你自己來體會了。

揹包問題示例**

C 程式設計之經典演算法 排序(十)

歸併排序 mergesort 歸併 merge 排序法是將兩個 或兩個以上 有序表合併成乙個新的有序表,即把待排序序列分為若干個子串行,每個子串行是有序的。然後再把有序子串行合併為整體有序序列。歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conque...

C 多執行緒程式設計之四

例程4 multithread4 該例程測試在windows下最多可建立執行緒的數目。建立乙個基於對話方塊的工程multithread4,在對話方塊idd multithread4 dialog中加入乙個按鈕idc test和乙個編輯框idc count,按鈕標題為 測試 編輯框屬性選中read o...

C 實現遞迴演算法經典例項

目錄 在數學與電腦科學中,遞迴是指在函式的定義中使用函式自身的方法。遞迴演算法是一種直接或者間接地呼叫自身演算法的過程。在計算機編寫程式中,遞迴演算法對解決一大類問題是十分有效的,它往往使演算法的描述簡潔而且易於理解。遞迴演算法解決問題的特點 1 遞迴就是在過程或函式裡呼叫自身。2 在使用遞迴策略時...