💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
动态规划的用法——01背包问题 <table border="1" style="font-family:Simsun; border-collapse:collapse; width:80%; padding:0pt 5.4pt"><tbody><tr><td width="882" valign="top" style="width:661.75pt; padding:0pt 5.4pt; border:0.5pt solid rgb(0,0,0)"><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:14pt; font-family:宋体"><strong>问题主题:</strong></span><span style="font-size:14pt; font-family:宋体">著名的</span><span style="font-size:14pt; font-family:宋体">01<span style="font-family:宋体">背包问题</span></span><span style="font-size:14pt; font-family:宋体"/></p></td></tr><tr><td width="882" valign="top" style="width:661.75pt; padding:0pt 5.4pt; border-left-width:0.5pt; border-style:none solid solid; border-left-color:rgb(0,0,0); border-right-width:0.5pt; border-right-color:rgb(0,0,0); border-bottom-width:0.5pt; border-bottom-color:rgb(0,0,0)"><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:14pt; font-family:宋体"><strong>问题描述:</strong></span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'; text-indent:28pt"><span style="font-size:14pt; font-family:宋体">有<span style="font-family:Times New Roman">n</span><span style="font-family:宋体">个重量和价值分别为</span><span style="font-family:Times New Roman">w</span></span><span style="font-size:14pt; font-family:宋体; vertical-align:sub">i</span><span style="font-size:14pt; font-family:宋体">、<span style="font-family:Times New Roman">v</span></span><span style="font-size:14pt; font-family:宋体; vertical-align:sub">i</span><span style="font-size:14pt; font-family:宋体">的物品,现在要从这些物品中选出总重量不超过<span style="font-family:Times New Roman">W</span><span style="font-family:宋体">的物品,求所有挑选方案中的价值最大值。</span></span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:14pt; font-family:宋体"><strong>限制条件:</strong></span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'; text-indent:28pt"><span style="font-size:14pt; font-family:宋体">1&lt;=</span><span style="font-size:14pt; font-family:宋体">N</span><span style="font-size:14pt; font-family:宋体">&lt;=</span><span style="font-size:14pt; font-family:宋体">10</span><span style="font-size:14pt; font-family:宋体">0</span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'; text-indent:28pt"><span style="font-size:14pt; font-family:宋体">1&lt;=</span><span style="font-size:14pt; font-family:宋体">w</span><span style="font-size:14pt; font-family:宋体; vertical-align:sub">i </span><span style="font-size:14pt; font-family:宋体">、</span><span style="font-size:14pt; font-family:宋体">v</span><span style="font-size:14pt; font-family:宋体; vertical-align:sub">i</span><span style="font-size:14pt; font-family:宋体">&lt;=</span><span style="font-size:14pt; font-family:宋体">10</span><span style="font-size:14pt; font-family:宋体">0</span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'; text-indent:28pt"><span style="font-size:14pt; font-family:宋体">1&lt;=</span><span style="font-size:14pt; font-family:宋体">w</span><span style="font-size:14pt; font-family:宋体; vertical-align:sub">i</span><span style="font-size:14pt; font-family:宋体">&lt;=</span><span style="font-size:14pt; font-family:宋体">10</span><span style="font-size:14pt; font-family:宋体">0</span><span style="font-size:14pt; font-family:宋体">00</span><span style="font-size:14pt; font-family:宋体"/></p></td></tr><tr><td width="882" valign="top" style="width:661.75pt; padding:0pt 5.4pt; border-left-width:0.5pt; border-style:none solid solid; border-left-color:rgb(0,0,0); border-right-width:0.5pt; border-right-color:rgb(0,0,0); border-bottom-width:0.5pt; border-bottom-color:rgb(0,0,0)"><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:14pt; font-family:宋体"><strong>样例:</strong></span><span style="font-size:14pt; font-family:宋体"><strong/></span></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:14pt; font-family:宋体">输入</span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'; text-indent:27pt"><span style="font-size:14pt; font-family:宋体">N</span><span style="font-size:14pt">=4</span><span style="font-size:14pt"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'; text-indent:27pt"><span style="font-size:14pt; font-family:宋体">W[N] = {2, 1, 3, 2}</span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'; text-indent:27pt"><span style="font-size:14pt; font-family:宋体">V[N] = {3, 2, 4, 2}</span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:14pt; font-family:宋体">输出</span><span style="font-size:14pt; font-family:宋体"/></p><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'; text-indent:27pt"><span style="font-size:14pt; font-family:宋体">W = 5(<span style="font-family:宋体">选择</span><span style="font-family:Times New Roman">0</span><span style="font-family:宋体">,</span><span style="font-family:Times New Roman">1</span><span style="font-family:宋体">,</span><span style="font-family:Times New Roman">3</span><span style="font-family:宋体">号</span><span style="font-family:Times New Roman">)</span></span><span style="font-size:14pt; font-family:宋体"/></p></td></tr></tbody></table> ### 【解法一】 ### 解题分析:    用普通的递归方法,对每个物品是否放入背包进行搜索 ### 程序实现: **C++** <table border="1" style="font-family:Simsun; border-collapse:collapse; width:80%; padding:0pt 5.4pt"><tbody><tr><td width="882" valign="top" style="width:661.8pt; padding:0pt 5.4pt; border:0.5pt solid rgb(0,0,0)"><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-family:宋体; font-size:10.5pt"/></p><pre code_snippet_id="163214" snippet_file_name="blog_20140119_1_8512058" name="code" class="cpp">#include &lt;stdio.h&gt; #include &lt;tchar.h&gt; #include &lt;queue&gt; #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 &gt;= N) return result; if(weight[i] &gt; 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 &lt;&lt; result &lt;&lt; endl; return 0; }</pre><br/> <p/></td></tr></tbody></table> **** ### 【解法二】 ### 解题分析:    用记录结果再利用的动态规划的方法,上面用递归的方法有很多重复的计算,效率不高。我们可以记录每一次的计算结果,下次要用时再直接去取,以提高效率 ### 程序实现: **C++** <table border="1" style="font-family:Simsun; border-collapse:collapse; width:80%; padding:0pt 5.4pt"><tbody><tr><td width="882" valign="top" style="width:661.8pt; padding:0pt 5.4pt; border:0.5pt solid rgb(0,0,0)"><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:10.5pt; font-family:Vijaya"/></p><pre code_snippet_id="163214" snippet_file_name="blog_20140119_2_8544295" name="code" class="cpp">#include &lt;stdio.h&gt; #include &lt;tchar.h&gt; #include &lt;queue&gt; #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 &lt; N; i ++) { for(int j = 0; j &lt; 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 &gt;= N) return result; if(weight[i] &gt; 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 &lt;&lt; result &lt;&lt; endl; return 0; }</pre><br/><span style="font-size:10.5pt; font-family:宋体"/><p/></td></tr></tbody></table> **Java** <table border="1" style="font-family:Simsun; border-collapse:collapse; width:80%; padding:0pt 5.4pt"><tbody><tr><td width="882" valign="top" style="width:661.8pt; padding:0pt 5.4pt; border:0.5pt solid rgb(0,0,0)"><p class="p0" style="margin:0pt; text-align:justify; font-size:10.5pt; font-family:'Times New Roman'"><span style="font-size:14pt; font-family:宋体"><strong/></span></p><pre code_snippet_id="163214" snippet_file_name="blog_20140119_3_2862694" name="code" class="java">package greed; /** * User: luoweifu * Date: 14-1-21 * Time: 下午5:13 */ 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 &lt; n; i ++) { for(int j = 0; j &lt; m; j ++) { record[i][j] = -1; } } } public int solve(int i, int residue) { if(record[i][residue] &gt; 0) { return record[i][residue]; } int result; if(i &gt;= stuffs.length) { return 0; } if(stuffs[i].getWeight() &gt; 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; } }</pre><br/><br/><pre/></td></tr></tbody></table> **** ### 算法复杂度:    时间复杂度O(NW)