0-1背包问题:输出最小背包
如何输出最小背包?
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)0/1背包问题
点击上方"Jerry的算法和NLP",选择"星标"公众号 重磅干货,第一时间送达 背包问题是一个经典的动态规划模型.它既简单形象容易理解,又在某种程 ...
- 八十九、动态规划系列背包问题之完全背包
@Author:Runsen @Date:2020/9/15 动态规划需要搞定三个系列:三个背包,零钱问题和股票问题.今天就开始干掉三个背包问题. 三个背包问题:01背包,多重背包,完全背包.上次搞定 ...
- 分枝定界法解0/1背包问题
分枝定界法解0/1背包问题 关键词:分支定界.0-1背包 分枝定界法简介 分枝定界法按照树形结构来组织解空间,展开节点后,有两种策略: 策略一.把节点加入 FIFO 队列当中: 策略二.把节点加入到堆 ...
- 多米诺骨牌——变形版0,1背包问题
多米诺骨牌--变形版0,1背包问题 1.题目描述 2.问题分析 3.算法源码 1.题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的上方块中点数之和记为S1,下方块中点数之和 ...
- 0-1背包问题和部分背包(fractional knapsack)问题分析
简介 背包问题已经是一个很经典而且讨论很广泛的算法问题了.最近学习到这一部分,打算结合自己思考和编码的过程做一个思考总结.这里主要讨论的0-1背包问题和部分背包问题解决方法背后其实隐藏了两种我们比较常 ...
- 0/1背包问题——动态规划、回溯、分支限界法对比
0/1背包问题--动态规划.回溯.分支限界法对比 2017.12.19 20:42:02 字数 3713 阅读 2820 目录 1.问题描述 1.1 问题描述 1.2 问题的数学表示(规划类问题,此种 ...
- 九十一、动态规划系列 背包问题之混合背包
@Author:Runsen @Date:2020/09/27 背包系列,是动态规划里一类典型的问题,主要有:01背包,完全背包,多重背包,混合背包,二维费用背包,分组背包,有依赖背包和泛化物品等.也 ...
- 0/1背包问题-----动态规划求解
问题描述 有n个物品和一个容量为c的背包,从n个物品中选取装包的物品.物品i的重量为w[i],价值为p[i].一个可行的背包装载是指,装包的物品总重量不超过背包的重量.一个最佳背包装载是指,物品总价值 ...
- 【动态规划】0/1背包问题
问题 H: [动态规划]0/1背包问题 时间限制: 1 Sec 内存限制: 64 MB 提交: 152 解决: 95 [提交] [状态] [讨论版] [命题人:admin] 题目描述 张琪曼和李旭 ...
最新文章
- 快速适应性很重要,但不是元学习的全部目标
- 打造交叉复合型数据人才的高地:清华大学大数据能力提升项目宣讲会成功举行!...
- python自学网站有哪些-Python自学之路-前期准备
- 让JTextField添加“自动完成”功能
- Windows11——Modern Standby(现代待机) S0改Suspend to RAM(待机到内存)S3睡眠解决方案
- 为什么物联网与云计算是天作之合
- java检测安卓程序退出_java – 退出应用程序时的Android停止服务
- win10 桌面图标变宽
- 51驱动AD9833
- cesium接入天地图影像与注记(经纬度)(cesium篇.70)
- antDesignPro大坑 Maxium call stack size exceeded
- .NET Core使用微软官方类库实现汉字简繁切换以及转拼音
- 明源云与华为联合发起828 B2B企业节,共同成就好生意!
- asp.net图书馆管理系统案例
- 达梦数据库DM8的DM管理工具manger命令行启动时出错Manager:10369的处理方法
- Mac版Sublime Text3搭建c语言环境
- DC-DC电压基准芯片和REF芯片
- MATLAB:预设矩阵的大小与不预设的时间差距
- 第四章课后习题-用Python实现羊车门问题,最大公约数计算,猜字游戏,统计不同字符个数。
- python快速开发app_python 使用Airtest超快速开发App爬虫
热门文章
- d3.js 旋转图形_一个简单易用但功能强大的图形矢量化软件,扫描图片转换成CAD图的软件等等...
- 毕业后成为大厂职业游戏建模师?门槛高不高,一看就知道
- python相关pyc文件的编译、运行和反编译
- HTML界面多语言切换
- Win10家庭版找不到组策略gpedit.msc怎么办
- 【imessage苹果推】苹果邮箱推邮箱Apple Push IMESSage SMS
- Python全栈(八)Flask项目实战之6.前台注册功能开发
- Accurate, Dense, and Robust Multi-View Stereopsis论文分析与代码实现(一)
- 攻击CSK靶机环境并学习linux渗透思路
- 【编译原理】 三地址语句的具体实现