dp动态规划 0-1背包

发布时间:2026/10/7 15:24:23
dp动态规划 0-1背包 0-1 knapsack Problem问题背景超市赢家商品价格体积 啤酒2410 汽水23 饼干94 面包105 牛奶94超市允许顾客使用一个体积大小为13的背包选择一件或多件商品带走如何带走总价最多的商品inputn个商品组成的集合O每个商品有两个属性Vi体积Pi价格output求解一个商品子集S0- max蛮力枚举枚举共2n−12^n-12n−1种KnapsackSR(h,i,c)在第个到第个商品中容量为时最优解选择啤酒Knapsack(1,4,3)24不选择啤酒Knapsack(1,4,13)KnapsackSR(1,5,13)max{KnapsackSR(1,4,3)24,KnapsackSR(1,4,13)}—KnapsackSR(h,i,c)max{KnapsackSR(h,i-1,c-vi)pi,KnapsackSR(h,i,c)}//全局变量#defineINF1000000intp[MAXN],v[MAXN],;intmax(inta,intb){if(ab){returna;}elsereturnb;}intKnapsackSR(inth,inti,intc){if(c0){return-INF;}elseif(ih-1){return0;}intp,p1,p2;p1KnapsackSR(h,i-1,c-v[i])p[i];p2KnapsackSR(h,i-1,c);pmax(p1,p2);returnp;}选–KnapsackSR(h,i-1,c-vi)pi不选–pi,KnapsackSR(h,i,c)–精简掉hKnapsackSR(, )前个商品中容量为时最优解intmax(inta,intb){if(ab){returna;}elsereturnb;}intKnapsackSR(inti,intc){if(c0){return-INF;}elseif(i0){return0;}intp,p1,p2;p1KnapsackSR(i-1,c-v[i])p[i];p2KnapsackSR(i-1,c);pmax(p1,p2);//最优子问题returnp;}递归树时间复杂度O(2n)O(2^n)O(2n)重复的求解了大量子问题中间的(n-3,c-2v)这种是重复问题—做一个备忘录存住子问题如果有直接用没有再算他的值带备忘录的递归记录子问题的解避免重复计算KnapsackMR(i,c)intput:商品集合{1,…,i},背包容量coutput最大总价格P[ i , c ]//全局变量intP[MAX_N][MAX_C];//备忘录intv[MAX_N],p[MAX_N];//体积和价格intKnapsackMR(inti,intc){if(c0){return-INF;}elseif(i0){return0;}if(P[i][c]!NULL){//检查是否记录记录了就直接用returnP[i][c];}intp1,p2;p1KnapsackMR(i-1,c-v[i])p[i];//选第i个p2KnapsackMR(i-1,c);//不选第i个P[i][c]max(p1,p2);returnP[i][c];}p[i][c]p[i][c]p[i][c]表示在前i个商品中选择背包容量为c时的最优解自顶向下自底向上能否不递归直接求解p[i][c]p[i][c]p[i][c]?P[ i , c ]只有两种来源P[i-1,c]未选中P[i-1,c-vi]pi选中从左往右从上往下一行一行往下扫先要初始化给好p[0,c]p[i,0]都赋值为0给好初值实例找到了最优解那么如何确定选取了哪些商品呢递推求解最优解追踪递推公式[ , ] {[ − , − ] ,[ − , ]}记录决策过程rec [ i , c ] 1 选择商品 P[i,c] P[i-1,c-vi]pi 就要往回找去到P[i-1,c-vi] 0 不选商品 (P[i,c]P[i-1,c])就往上找去P[i-1,c]KnapsackDP(n,p,v,C)input:商品数量n,各商品的价值p各商品的体积u背包容量Coutput:商品价格的最大值最优解万案intKnapsackDP(intn,intC){for(inti0;iC;i){P[0][i]0;}for(inti0;in;i){P[i][0]0;}//初始化for(inti1;in;i){for(intc1;cC;c){if(v[i]c(p[i]P[i-1][c-v[i]]P[i-1][c]){//能选没超且应该选的确价格更高P[i][c]P[i-1][c-v[i]]p[i];rec[i][c]1;}else{//不选P[i][c]P[i-1][c];rec[i][c]0;}}}//输出最优方案intkC;for(intin;i1;i--){//倒着找if(rec[i][k]1){printf(选择物品 %d\n,i);kk-v[i];}else{printf(不选%d\n,i);}}returnP[n][C];}O(n * c)问题结构分析-递推关系建立-自底向上计算-最优方案追踪问题结构分析给出问题表示[, ]前个商品可选、背包容量为时的最大总价格递推关系建立分析最优子结构问题的最优解由相关子问题最优解组合而成子问题可以独立求解构造递推公式 , {[ −, ], [ − , − ]}自底向上计算确定计算顺序[, ]依赖于子问题[ − , −]和[ − , ]依次求解从左往右从上往下最优方案追踪记录决策过程rec [ i , c ]输出最优方案倒序判断是否选择商品 1 选择商品 P[i,c] P[i-1,c-vi]pi 就要往回找去到P[i-1,c-vi] 0 不选商品 (P[i,c]P[i-1,c])就往上找去P[i-1,c]如果要记录有几种方案

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询