今天继续给大家带来一道一本通上的题目
1267:【例9.11】01背包问题
时间限制: 1000 ms 内存限制: 65536 KB
【题目描述】
一个旅行者有一个最多能装 <span id="MathJax-Span-2" class="mrow"><span id="MathJax-Span-3" class="mi">MM 公斤的背包,现在有 <span id="MathJax-Span-5" class="mrow"><span id="MathJax-Span-6" class="mi">nn 件物品,它们的重量分别是<span id="MathJax-Span-8" class="mrow"><span id="MathJax-Span-9" class="msubsup"><span id="MathJax-Span-10" class="mi">W<span id="MathJax-Span-11" class="mn">1<span id="MathJax-Span-12" class="texatom"><span id="MathJax-Span-13" class="mrow"><span id="MathJax-Span-14" class="mo">,<span id="MathJax-Span-15" class="msubsup"><span id="MathJax-Span-16" class="mi">W<span id="MathJax-Span-17" class="mn">2<span id="MathJax-Span-18" class="texatom"><span id="MathJax-Span-19" class="mrow"><span id="MathJax-Span-20" class="mo">,<span id="MathJax-Span-21" class="mo">.<span id="MathJax-Span-22" class="mo">.<span id="MathJax-Span-23" class="mo">.<span id="MathJax-Span-24" class="mo">,<span id="MathJax-Span-25" class="msubsup"><span id="MathJax-Span-26" class="mi">W<span id="MathJax-Span-27" class="mi">nW1,W2,...,Wn,它们的价值分别为<span id="MathJax-Span-29" class="mrow"><span id="MathJax-Span-30" class="msubsup"><span id="MathJax-Span-31" class="mi">C<span id="MathJax-Span-32" class="mn">1<span id="MathJax-Span-33" class="mo">,<span id="MathJax-Span-34" class="msubsup"><span id="MathJax-Span-35" class="mi">C<span id="MathJax-Span-36" class="mn">2<span id="MathJax-Span-37" class="mo">,<span id="MathJax-Span-38" class="mo">.<span id="MathJax-Span-39" class="mo">.<span id="MathJax-Span-40" class="mo">.<span id="MathJax-Span-41" class="mo">,<span id="MathJax-Span-42" class="msubsup"><span id="MathJax-Span-43" class="mi">C<span id="MathJax-Span-44" class="mi">nC1,C2,...,Cn,求旅行者能获得最大总价值。
【输入】
第一行:两个整数,<span id="MathJax-Span-46" class="mrow"><span id="MathJax-Span-47" class="mi">MM(背包容量,<span id="MathJax-Span-49" class="mrow"><span id="MathJax-Span-50" class="mi">M<span id="MathJax-Span-51" class="mo"><=<span id="MathJax-Span-52" class="mn">200M<=200)和<span id="MathJax-Span-54" class="mrow"><span id="MathJax-Span-55" class="mi">NN(物品数量,<span id="MathJax-Span-57" class="mrow"><span id="MathJax-Span-58" class="mi">N<span id="MathJax-Span-59" class="mo"><=<span id="MathJax-Span-60" class="mn">30N<=30);
第<span id="MathJax-Span-62" class="mrow"><span id="MathJax-Span-63" class="mn">2..<span id="MathJax-Span-64" class="mi">N<span id="MathJax-Span-65" class="mo">+<span id="MathJax-Span-66" class="mn">12..N+1行:每行二个整数<span id="MathJax-Span-68" class="mrow"><span id="MathJax-Span-69" class="msubsup"><span id="MathJax-Span-70" class="mi">W<span id="MathJax-Span-71" class="mi">i<span id="MathJax-Span-72" class="texatom"><span id="MathJax-Span-73" class="mrow"><span id="MathJax-Span-74" class="mo">,<span id="MathJax-Span-75" class="msubsup"><span id="MathJax-Span-76" class="mi">C<span id="MathJax-Span-77" class="mi">iWi,Ci,表示每个物品的重量和价值。
【输出】
仅一行,一个数,表示最大总价值。
【输入样例】
10 4 2 1 3 3 4 5 7 9
【输出样例】
12
(本题思路不唯一,有多种解法,这里只介绍一种)。
【题目思路】:
我们可以先定义两个一维数组和一个二维数组,输入容量和物品数量,将这个问题化解为多个子问题,
物品看成i,容量看成j转化为“将前i-1中物品放入容量为j-w[i]的背包中获得的最大价值c[i-1][j-w[i]]”,加上第i种物品的价值v[i],
即为c[i-1][j-w[i]]+v[i];(注意被背包容量),以上说的可能不太好理解。
举个栗子:
加上这幅图就好理解了。我们最终要求的是最大,所以最后输出c[n][m]就可以了。
【代码思路】:
【参考代码】:
#include<bits/stdc++.h> #define ll long long using namespace std; ll n,m,a[10001],b[10001],c[10001][10001]; int main(){ cin>>m>>n; for(int i=1;i<=n;i++) cin>>a[i]>>b[i]; for(int i=1;i<=n;i++){ for(int j=0;j<=m;j++){ c[i][j]=c[i-1][j]; if(j>=a[i]){ c[i][j]=max(c[i-1][j],c[i-1][j-a[i]]+b[i]); } } } cout<<c[n][m]; return 0; }
见!!!