ahu university算法设计考试
1.實驗要求:
給定n種物品和一背包。物品i的重量是wi,體積是bi,其價值為vi,背包的容量為c,容積為d。問應如何選擇裝入背包中的物品,使得裝入背包中物品的總價值最大?在選擇裝入背包的物品時,對每種物品i只有兩種選擇,即裝入背包或不裝入背包。不能將物品i裝入背包多次,也不能只裝入部分的物品i。試設計一個解此問題的動態規劃算法,并分析算法的計算復雜性。
2.實驗代碼:
#include <iostream> using namespace std; const int MAX = 32768; int dp[10][10][10] = { 0 }; //dp[i][j][k] i代表著第1到第i個物品,j代表的是重量,k代表的是容積,dp為最優價值class bag { public:void init_bag(){cout << "請輸入背包的容量,容積:";cin >> c >> d;}int c;int d; };class object { public:friend void dp_do(bag mybag, object t);int n;int w[MAX] = { 0 }; //重量int b[MAX] = { 0 }; //體積int v[MAX] = { 0 }; //價值void initthings(){cout << "總共需要整理的物品數目:";cin >> n;cout << "物品的重量,體積,價值:" << endl;for (int i = 1; i < n + 1; i++){cin >> w[i] >> b[i] >> v[i];}} };void dp_do(bag mybag, object t) {for (int i = 1; i < t.n + 1; i++)for (int j = 1; j <= mybag.c; j++)for (int k = 1; k <= mybag.d; k++){if (t.w[i] <= j && t.b[i] <= k) //當前物品重量小于當前容量,且體積小于容積時 ,才可以考慮裝入物品的問題dp[i][j][k] = max(dp[i - 1][j][k], dp[i - 1][j - t.w[i]][k - t.b[i]] + t.v[i]);else dp[i][j][k] = dp[i - 1][j][k];}cout << "背包的最大價值為:" << dp[t.n][mybag.c][mybag.d] << endl; }void marke(bag mybag, object t) {int x[MAX] = { 0 }; //記錄是否被選中for (int i = t.n; i > 1; i--)if (dp[i][mybag.c][mybag.d] == dp[i - 1][mybag.c][mybag.d])x[i] = 0;else { x[i] = 1; mybag.c -= t.w[i]; mybag.d -= t.b[i]; }x[1] = (dp[1][mybag.c][mybag.d]) ? 1 : 0;cout << "選入物品的編號,質量和體積,價值分別是:" << endl;for (int i = 1; i < t.n + 1; i++)if (x[i] == 1)cout << "第" << i << "個選中物品: \n" << t.w[i] << " " << t.b[i] << " " << t.v[i] << endl; }int main() {bag mybag;object t;mybag.init_bag();t.initthings();dp_do(mybag, t);marke(mybag, t);return 0; }3.代碼解釋
本代碼使用了兩個類來儲存物品以及背包使程序的閱讀性更強,一開始我們優先定義了整個代碼都需要使用的二維dp列表,通過二維列表當中的值的運算進行題目的運算。同時我們定義了兩個不同的類——背包類和物品類,通過背包類和物品類當中的傳入物品的操作,對數據進行輸入。接著我定義了兩個函數,分別為dp_do函數以及marke函數對dp數據表進行處理。Dp_do函數通過我們已經有的公式選或者不選公式對dp表進行更新,賦值。Marke函數通過對dp表當中前后數據的比對,確認是否有對物品進行選擇,并且將是否選擇了物品記錄到記錄表當中。最后在每一個函數當中我或多或少加入了一些輸入輸出語句使得程序更加易于使用和理解。
4.實驗結果截屏
?5.算法復雜度分析
動態規劃算法通常用于求解具有某種最優性質的問題。其基本思想也是將待求解問題分解成若干個子問題,先求解子問題,然后從這些子問題的解得到原問題的解。與分治法不同的是,適合于用動態規劃求解的問題,經分解得到子問題往往不是互相獨立的。若用分治法來解這類問題,則分解得到的子問題數目太多,有些子問題被重復計算了很多次。如果我們能夠保存已解決的子問題的答案,而在需要時再找出已求得的答案,這樣就可以避免大量的重復計算,節省時間。我們可以用一個表來記錄所有已解的子問題的答案。不管該子問題以后是否被用到,只要它被計算過,就將其結果填入表中。這就是動態規劃法的基本思路。具體的動態規劃算法多種多樣,但它們具有相同的填表格式。 與分治法最大的差別是:適合于用動態規劃法求解的問題,經分解后得到的子問題往往不是互相獨立的(即下一個子階段的求解是建立在上一個子階段的解的基礎上,進行進一步的求解)
動態規劃的時間效率為O(ncd)其中n表示物品的個數,c表示背包的容量,d表示背包的容積。空間的效率就是用于存儲二維數組的占用空間大小,即為O(ncd).
總結
以上是生活随笔為你收集整理的ahu university算法设计考试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【安卓学习之常见问题】 Google P
- 下一篇: XiaoHu日志 7/29~8/9