如何输出最小背包?

0-1背包
#include <iostream>
using namespace std;
const int maxn=1005;
int dp[maxn][maxn];
int weight[maxn];
int value[maxn];
int n,v;
int max(int a,int b){if(a>b) return a;return b;
}
int main(int argc, char const *argv[])
{int T;cin>>T;while(T--){cin>>n>>v;for(int i=1;i<=n;i++){cin>>value[i];}for(int i=1;i<=n;i++){cin>>weight[i];}memset(dp,0,sizeof(dp));for(int i=1;i<=n;i++){for(int j=v;j>=weight[i];j--){dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);}}int out=dp[1][v];for(int k=2;k<=n;k++)out = max(out,dp[k][v]);cout<<out<<endl;}/* code */return 0;
}

其中i表示放第i个物品,j表示背包所容纳的重量,那么tab[i-1][j-weight[i]]+value[i]表示放入第i物品,刚开始接触会有疑问,tab[i-1][j-weight[i]]这个值,可以这样理解:tab[i-1][j]为装到上一个物品在背包j容量时的最佳值,那么如果我要求在j容量的时候放入现在的i物品的价值,那么是不是要先得到容量为(j-weight[i])时候的价值,即先得到 tab[i-1][j-weight[i]] ,所以 tab[i-1][j-weight[i]]+value[i] 为放入第i物品的价值; tab[i-1][j] 就是不放入第i个物品。

但是以上的做法是错误的

由于这样只更新了j>W[i]的情况,对于下一件物品,如果它的W[i+1]<[i],那么很可能这个W[i][j]为O,这就会导致错误

所以下标只能从J=O开始

for(int i=1;i<=n;i++){for(int j=0;j>=weight[i];j--){
<span style="white-space:pre">              </span>if(j<w[i]) dp[i][j]=dp[i-1][j]
<span style="white-space:pre">             </span>else<span style="white-space:pre">                </span>
             dp[i][j]=max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);}}

优化空间复杂度以后

#include <iostream>
const int maxn=1005;
using namespace std;
int weight[maxn];
int value[maxn];
int dp[maxn];
int max(int a,int b){return a>b?a:b;
}
int main(int argc, char const *argv[])
{int T;cin>>T;int N,V;while(T--){cin>>N>>V;for(int i=0;i<N;i++){cin>>value[i];}for(int i=0;i<N;i++){cin>>weight[i];}memset(dp,0,sizeof(dp));for(int i=0;i<N;i++){for(int j=V;j>=weight[i];j--){dp[j]=max(dp[j],dp[j-weight[i]]+value[i]);}}cout<<dp[V]<<endl;}/* code */return 0;
}

为什么从后面到前面?因为后面到前面不会影响前面的状态。如果是从前到后,可能包含了一个物品取多个的情况。

事实上,从前往后正是完全背包的做法

明确状态转移方程的意义。状态转移在与是否取第M个物品,如果取第M个物品,那么这个位置就标为M,用一个chose数组记录是否选取M,然后通过回溯确定某个位置是否为1

#include <iostream>
using namespace std;
const int maxn=10005;
int dp[maxn];
int w[maxn];
int v[maxn];
bool chose[maxn][maxn];
int max(int a,int b){return a>b?a:b;
}
int out[maxn];
int indexofout;
void print(int m,int v){if(m==0) return ;if(!chose[m][v])print(m-1,v);else {out[indexofout++]=m;print(m-1,v-w[m]);}
}
int main(int argc, char const *argv[])
{int N,V;int T;cin>>T;while(T--){cin>>N>>V;indexofout = 0;memset(dp,0,sizeof(dp));memset(chose,false,sizeof(chose));for(int i=1;i<=N;i++){cin>>v[i];}for(int i=1;i<=N;i++){cin>>w[i];}for(int i=1;i<=N;i++){for(int j=V;j>=w[i];j--){dp[j]=max(dp[j],dp[j-w[i]]+v[i]);if(dp[j]==dp[j-w[i]]+v[i]) chose[i][j]=true;}}print(N,V);for(int i=0;i<indexofout;i++){cout<<out[i]<<" ";}cout<<endl;cout<<dp[V]<<endl;}return 0;
}

0-1背包问题:输出最小背包相关推荐

  1. 令人头疼的背包九讲(1)0/1背包问题

    点击上方"Jerry的算法和NLP",选择"星标"公众号       重磅干货,第一时间送达 背包问题是一个经典的动态规划模型.它既简单形象容易理解,又在某种程 ...

  2. 八十九、动态规划系列背包问题之完全背包

    @Author:Runsen @Date:2020/9/15 动态规划需要搞定三个系列:三个背包,零钱问题和股票问题.今天就开始干掉三个背包问题. 三个背包问题:01背包,多重背包,完全背包.上次搞定 ...

  3. 分枝定界法解0/1背包问题

    分枝定界法解0/1背包问题 关键词:分支定界.0-1背包 分枝定界法简介 分枝定界法按照树形结构来组织解空间,展开节点后,有两种策略: 策略一.把节点加入 FIFO 队列当中: 策略二.把节点加入到堆 ...

  4. 多米诺骨牌——变形版0,1背包问题

    多米诺骨牌--变形版0,1背包问题 1.题目描述 2.问题分析 3.算法源码 1.题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的上方块中点数之和记为S1,下方块中点数之和 ...

  5. 0-1背包问题和部分背包(fractional knapsack)问题分析

    简介 背包问题已经是一个很经典而且讨论很广泛的算法问题了.最近学习到这一部分,打算结合自己思考和编码的过程做一个思考总结.这里主要讨论的0-1背包问题和部分背包问题解决方法背后其实隐藏了两种我们比较常 ...

  6. 0/1背包问题——动态规划、回溯、分支限界法对比

    0/1背包问题--动态规划.回溯.分支限界法对比 2017.12.19 20:42:02 字数 3713 阅读 2820 目录 1.问题描述 1.1 问题描述 1.2 问题的数学表示(规划类问题,此种 ...

  7. 九十一、动态规划系列 背包问题之混合背包

    @Author:Runsen @Date:2020/09/27 背包系列,是动态规划里一类典型的问题,主要有:01背包,完全背包,多重背包,混合背包,二维费用背包,分组背包,有依赖背包和泛化物品等.也 ...

  8. 0/1背包问题-----动态规划求解

    问题描述 有n个物品和一个容量为c的背包,从n个物品中选取装包的物品.物品i的重量为w[i],价值为p[i].一个可行的背包装载是指,装包的物品总重量不超过背包的重量.一个最佳背包装载是指,物品总价值 ...

  9. 【动态规划】0/1背包问题

    问题 H: [动态规划]0/1背包问题 时间限制: 1 Sec  内存限制: 64 MB 提交: 152  解决: 95 [提交] [状态] [讨论版] [命题人:admin] 题目描述 张琪曼和李旭 ...

最新文章

  1. 快速适应性很重要,但不是元学习的全部目标
  2. 打造交叉复合型数据人才的高地:清华大学大数据能力提升项目宣讲会成功举行!...
  3. python自学网站有哪些-Python自学之路-前期准备
  4. 让JTextField添加“自动完成”功能
  5. Windows11——Modern Standby(现代待机) S0改Suspend to RAM(待机到内存)S3睡眠解决方案
  6. 为什么物联网与云计算是天作之合
  7. java检测安卓程序退出_java – 退出应用程序时的Android停止服务
  8. win10 桌面图标变宽
  9. 51驱动AD9833
  10. cesium接入天地图影像与注记(经纬度)(cesium篇.70)
  11. antDesignPro大坑 Maxium call stack size exceeded
  12. .NET Core使用微软官方类库实现汉字简繁切换以及转拼音
  13. 明源云与华为联合发起828 B2B企业节,共同成就好生意!
  14. asp.net图书馆管理系统案例
  15. 达梦数据库DM8的DM管理工具manger命令行启动时出错Manager:10369的处理方法
  16. Mac版Sublime Text3搭建c语言环境
  17. DC-DC电压基准芯片和REF芯片
  18. MATLAB:预设矩阵的大小与不预设的时间差距
  19. 第四章课后习题-用Python实现羊车门问题,最大公约数计算,猜字游戏,统计不同字符个数。
  20. python快速开发app_python 使用Airtest超快速开发App爬虫

热门文章

  1. d3.js 旋转图形_一个简单易用但功能强大的图形矢量化软件,扫描图片转换成CAD图的软件等等...
  2. 毕业后成为大厂职业游戏建模师?门槛高不高,一看就知道
  3. python相关pyc文件的编译、运行和反编译
  4. HTML界面多语言切换
  5. Win10家庭版找不到组策略gpedit.msc怎么办
  6. 【imessage苹果推】苹果邮箱推邮箱Apple Push IMESSage SMS
  7. Python全栈(八)Flask项目实战之6.前台注册功能开发
  8. Accurate, Dense, and Robust Multi-View Stereopsis论文分析与代码实现(一)
  9. 攻击CSK靶机环境并学习linux渗透思路
  10. 【编译原理】 三地址语句的具体实现