生活随笔
收集整理的這篇文章主要介紹了
动态规划的用法——01背包问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
動態規劃的用法——01背包問題
?
| 問題主題:著名的01背包問題 |
| 問題描述: 有n個重量和價值分別為wi、vi的物品,現在要從這些物品中選出總重量不超過W的物品,求所有挑選方案中的價值最大值。 限制條件: 1<=N<=100 1<=wi?、vi<=100 1<=wi<=10000 |
| 樣例: 輸入 N=4 W[N]?=?{2,?1,?3,?2} V[N]?=?{3,?2,?4,?2} 輸出 W?=?5(選擇0,1,3號) |
?
?
【解法一】
解題分析:
????用普通的遞歸方法,對每個物品是否放入背包進行搜索
程序實現:
C++
| [cpp]?view plaincopyprint? #include?<stdio.h>?? #include?<tchar.h>?? #include?<queue>?? #include?"iostream"?? ??? using?namespace?std;?? ??? const?int?N?=?4;?? const?int?W?=?5;?? int?weight[N]?=?{2,?1,?3,?2};?? int?value[N]?=?{3,?2,?4,?2};?? int?solve(int?i,?int?residue)??? {?? int?result?=?0;?? if(i?>=?N)?? return?result;?? if(weight[i]?>?residue)?? result?=?solve(i+1,?residue);?? else??? {?? result?=?max(solve(i+1,?residue),?solve(i+1,?residue-weight[i])?+?value[i]);?? }?? ??? }?? ??? int?main()?{?? int?result?=?solve(0,?W);?? cout?<<?result?<<?endl;?? return?0;?? }?? ? |
?
【解法二】
解題分析:
????用記錄結果再利用的動態規劃的方法,上面用遞歸的方法有很多重復的計算,效率不高。我們可以記錄每一次的計算結果,下次要用時再直接去取,以提高效率
程序實現:
C++
| [cpp]?view plaincopyprint? #include?<stdio.h>?? #include?<tchar.h>?? #include?<queue>?? #include?"iostream"?? ?? using?namespace?std;?? ?? const?int?N?=?4;?? const?int?W?=?5;?? int?weight[N]?=?{2,?1,?3,?2};?? int?value[N]?=?{3,?2,?4,?2};?? int?record[N][W];?? void?init()?? {?? ????for(int?i?=?0;?i?<?N;?i?++)?? ????{?? ????????for(int?j?=?0;?j?<?W;?j?++)??? ????????{?? ????????????record[i][j]?=?-1;?? ????????}?? ????}?? }?? ?? int?solve(int?i,?int?residue)??? {?? ????if(-1?!=?record[i][residue])?? ????????return?record[i][residue];?? ????int?result?=?0;?? ????if(i?>=?N)?? ????????return?result;?? ????if(weight[i]?>?residue)?? ????{?? ????????record[i?+?1][residue]?=?solve(i+1,?residue);?? ?????????? ????}?? ????else??? ????{?? ????????result?=?max(solve(i+1,?residue),?solve(i+1,?residue-weight[i])?+?value[i]);?? ????}?? ????return?record[i?+?1][residue]?=?result;?? }?? ?? int?main()?{?? ????init();?? ????int?result?=?solve(0,?W);?? ????cout?<<?result?<<?endl;?? ????return?0;?? }?? |
Java
| [java]?view plaincopyprint? package?greed;?? ?? ? ? ? ? ?? public?class?Knapsack?{?? ????private?int?maxWeight;?? ????private?int[][]?record;?? ????private?Stuff[]?stuffs;?? ?? ????public?Knapsack(Stuff[]?stuffs,?int?maxWeight)?{?? ????????this.stuffs?=?stuffs;?? ????????this.maxWeight?=?maxWeight;?? ????????int?n?=?stuffs.length?+?1;?? ????????int?m?=?maxWeight+1;?? ????????record?=?new?int[n][m];?? ????????for(int?i?=?0;?i?<?n;?i?++)?{?? ????????????for(int?j?=?0;?j?<?m;?j?++)?{?? ????????????????record[i][j]?=?-1;?? ????????????}?? ????????}?? ????}?? ????public?int?solve(int?i,?int?residue)?{?? ????????if(record[i][residue]?>?0)?{?? ????????????return?record[i][residue];?? ????????}?? ????????int?result;?? ????????if(i?>=?stuffs.length)?{?? ????????????return?0;?? ????????}?? ????????if(stuffs[i].getWeight()?>?residue)?{?? ????????????result?=?solve(i?+?1,?residue);?? ????????}?else?{?? ????????????result?=?Math.max(solve(i?+?1,?residue),?? ?????????????????solve(i?+?1,?residue?-?stuffs[i].getWeight())?+?stuffs[i].getValue());?? ????????}?? ????????record[i][residue]?=?result;?? ????????return?result;?? ????}?? ?? ????public?static?void?main(String?args[])?{?? ????????Stuff?stuffs[]?=?{?? ????????????new?Stuff(2,?3),?? ????????????new?Stuff(1,?2),?? ????????????new?Stuff(3,?4),?? ????????????new?Stuff(2,?2)?? ????????};?? ????????Knapsack?knapsack?=?new?Knapsack(stuffs,?5);?? ????????int?result?=?knapsack.solve(0,?5);?? ????????System.out.println(result);?? ????}?? }?? ?? class?Stuff{?? ????private?int?weight;?? ????private?int?value;?? ?? ????public?Stuff(int?weight,?int?value)?{?? ????????this.weight?=?weight;?? ????????this.value?=?value;?? ????}?? ?? ????int?getWeight()?{?? ????????return?weight;?? ????}?? ?? ????void?setWeight(int?weight)?{?? ????????this.weight?=?weight;?? ????}?? ?? ????int?getValue()?{?? ????????return?value;?? ????}?? ?? ????void?setValue(int?value)?{?? ????????this.value?=?value;?? ????}?? }?? |
?
總結
以上是生活随笔為你收集整理的动态规划的用法——01背包问题的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。