Time Limit: 1000 MS Memory Limit: 32768 KB

Description
SQK上山去采药。SQK有一个容量为m(1<=m<=1000)的背包,他所采集的药材的总重量不能大于背包的容量。已知共有n(1<=n<=100 )种药材,每种药材都有自己的价值,并且知道每种药材的数量是有限的,如何选择,才能使得背包中药材价值最大?

Input
输入数据首先包含一个正整数C(1<=C<=10),表示有C组测试用例,每组测试用例的第一行是两个整数m和n(1<=m<=1000, 1<=n<=100),分别表背包的负重和药材的种类,然后是n行数据,每行包含3个数w,v和c(1<=w<=100,1<=v<=200,1<=c<=100),分别表示每种药材的重量、每株的价值以及对应种类药材的株数。

Output
对于每组测试数据,请输出能够采集药材的最大价值,每个实例的输出占一行。

Sample Input
1
8 2
2 100 4
4 100 2

Sample Output
400

Source
2016_SunQianKun

1.暴力
先来最暴力的解法,时间复杂度为O(n^3),就是多了相较于01背包多了一层循环枚举这次选几个,但要注意一定要加上能不能塞进去n个的判断

#include<iostream>
#include<cstring>
using namespace std;
int dp[1005];
int max(int x,int y)
{return x>y?x:y;
}
int main()
{int C;cin>>C;for(int i=1;i<=C;++i){memset(dp,0,sizeof(dp));int m,n;cin>>m>>n;int w,v,c;for(int j=1;j<=n;++j){cin>>w>>v>>c;for(int k=m;k>=w;--k){for(int p=1;p<=c&&p*w<=k;++p)//能不能塞进去p个的判断一定要加 {dp[k]=max(dp[k],dp[k-w*p]+v*p);}}}cout<<dp[m]<<endl;}return 0;
}

2.二进制优化
再来一个经过二进制优化过的方法,该方法的时间复杂度比上一个好了一些,是O(nnlog(2)n),该优化方式实际上就是将每个物品能拿的个数进行了二进制分解,然后将分解后的那几个分别当成独立的物品,存到物品数组中,然后就是01背包问题了,为什么能保证每个容量的背包的解是正确的?因为一个数字进行二进制分解后,利用分解出来的数字的组合可以至少从1表示到那个数字,但是要注意如果是像10这样无法完全进行二进制分解的数不要让分解后的数组合后可以比它大,因为最多就能装10件,多了装不了,因此我们只要最后剩下一个不能用2的几次方表示的数就行了,10可以分解为1,2,4,3,这些数经过组合可以表示出1-10中任意一个数。
下面是代码:

#include<iostream>
#include<cstring>
using namespace std;
int dp[1005];
struct data{int w;int v;
}grass[1005];//存放物品的数组
int max(int x,int y)
{return x>y?x:y;
}
int main()
{int C;cin>>C;for(int i=1;i<=C;++i){int grassi=1;memset(dp,0,sizeof(dp));int m,n;cin>>m>>n;for(int j=1;j<=n;++j){int w,v,c;cin>>w>>v>>c;for(int k=1;k<=c;k*=2)//二进制拆分 ,拆分出来的当成一个独立的物品 {c-=k;grass[grassi].v=v*k;grass[grassi++].w=w*k;}if(c>0)//将残余情况的加进去 {grass[grassi].v=v*c;grass[grassi++].w=w*c;}}for(int i=1;i<grassi;++i){for(int j=m;j>=grass[i].w;--j){dp[j]=max(dp[j],dp[j-grass[i].w]+grass[i].v);//01背包 }}cout<<dp[m]<<endl;}return 0;
}

3.单调队列优化

#include<iostream>
using namespace std;
const int maxn=20005;
int dp[maxn],que[maxn],book[maxn];
int max(int x,int y)
{return x>y?x:y;
}
int main()
{int W,N;cin>>N>>W;//N是有几种物品,W是背包最多能容纳的重量 for(int i=1;i<=N;++i){int w,v,c;cin>>w>>v>>c;//w是该物品的重量,v是该物品的价值,c是该物品最多能拿的数量 if(w*c>=W)//如果能拿的这一个物品拿最多的质量大于背包总共能装的质量,就可以用完全背包问题来处理。 {for(int ind=w;ind<=W;++ind){dp[ind]=max(dp[ind],dp[ind-w]+v);}}else{for(int ind=0;ind<w;++ind){int head=0,tail=0;for(int jnd=0;jnd<=(W-ind)/w;++jnd){int temp=dp[ind+jnd*w]-jnd*v;while(head<tail&&que[tail-1]<=temp)--tail;book[tail]=jnd;que[tail++]=temp;if(book[head]<jnd-c)++head;dp[ind+jnd*w]=que[head]+jnd*v;}}}}cout<<dp[W]<<endl;return 0;
}

SDNUOJ 1520.采药(多重背包问题)相关推荐

  1. P03: 多重背包问题

    P03: 多重背包问题 题目 有N种物品和一个容量为V的背包.第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和 ...

  2. 多维多重背包问题_满满干货!背包问题全总结(带c++源码)

    目录: 动态规划简介 0-1 背包问题 完全背包问题 多重背包问题 混合背包问题 二维(多维)费用背包问题 分组的背包问题 有依赖的背包问题 动态规划简介 在学习背包问题之前需要对动态规划有一定的了解 ...

  3. 01背包问题+完全背包问题+多重背包问题

    一 01背包问题 1.1题目 有N件物品和一个容量为V 的背包.放入第i件物品耗费的空间是Ci,得到 的价值是Wi. 求解将哪些物品装入背包可使价值总和最大. 1.2 基本思路 这是最基础的背包问题, ...

  4. 多重背包问题以及二进制优化

    2020.12.30开始学习AcWing算法<算法竞赛进阶指南>: 上传博客方便复习. 多重背包问题(N<= 100): //Wecccccccc //2020.12.31 #inc ...

  5. ACwing 5. 多重背包问题 II(二进制拆分+DP)

    文章目录 1. 题目 2. 解题 1. 题目 有 N 种物品和一个容量是 V 的背包. 第 i 种物品最多有 si 件,每件体积是 vi,价值是 wi. 求解将哪些物品装入背包,可使物品体积总和不超过 ...

  6. O(V*n)的多重背包问题

    多重背包问题: 有n件物品,第i件价值为wi,质量为vi,有c1件,问,给定容量V,求获得的最大价值. 朴素做法: 视为0,1,2,...,k种物品的分组背包 [每组只能选一个] f[i][j]=Ma ...

  7. 01背包、完全背包、多重背包问题的C++实现及路径记录

    这里主要实现路径记录,只求最值问题移步 01背包.完全背包.多重背包问题的C++实现 以下均打印输出路径,即装入背包的物品序号,和最大值. 01背包问题 #include <iostream&g ...

  8. 01背包、完全背包、多重背包问题的C++实现

    01背包问题 容量为10的背包,有5种物品,每种物品只有一个,其重量分别为5,4,3,2,1,其价值分别为1,2,3,4,5. 设计算法,实现背包内物品价值最大. 代码如下(输出14) #includ ...

  9. 九大背包问题专题--多重背包问题(二进制优化方法;单调队列问题)

    3.多重背包问题1 题目: 有N件物品和一个容量是V的背包. 第i种物品最多有si件,每件的体积是vi,价值是wi. 求解将哪些物品装入背包,可使这些物品的总体积不超过背包的容量,且价值总和最大. 输 ...

  10. 中医药暑假训练赛三 c题 题解 (多重背包问题)

    原题: Description 主角kirito是使用世界首款完全潜行游戏"刀剑神域(Sword Art Online)"的玩家.曾经很幸运的参与过封闭测试,并买下正式版的kiri ...

最新文章

  1. 局域网语音通话demo
  2. VC++学习笔记(BITMAP与CBitmap的区别)
  3. 使用第三方Markdown编辑器编辑为知笔记
  4. IPv4地址和IPv6地址的比较,IPv6地址及其表示
  5. 【转】asp.net中bind()和eval()的区别
  6. vs xgb 神经网络_业界 | 深度学习与XGBoost在小数据集上的测评,你怎么看?(附源码)...
  7. shell脚本语之运算符
  8. 《A Tour of PostgreSQL Internals》学习笔记——进程间通信
  9. python根据ip获取地理位置_使用python根据ip获取目标地理位置信息
  10. java连接mongo_java 连接mongodb
  11. SAP 批量下载表数据到EXCEL中
  12. 18个黑科技网站,你想要的软件都能找到,请收藏!!!
  13. SLIC超像素分割并保存分割得到的超像素块,python代码
  14. #paypay付款测试#
  15. oracle中cube的作用,Oraclerollup和cube分析
  16. CentOS 6.4x64编译安装DRBD及备节点同步后容量变小的处理
  17. 适应Linux32位的qq,Ubuntu 安装 QQ (简易安装 适合32位操作系统)
  18. UNIX环境高级编程笔记(14)- 函数sigsuspend 实现父进程子进程同步
  19. Mysql基础篇(5)—— 约束
  20. PCI与PCIe学习一——硬件篇

热门文章

  1. CentOS配置静态IP
  2. 数学基础(0)-- 高等数学、概率论与数理统计
  3. CE教程 第八章 《注入++》
  4. oracle登录卡,【Oracle连接问题】关于windows xp3上oracle连接登录卡住的问题
  5. Visual Studio 2015的破解密钥
  6. python 爬取网易云音乐歌单
  7. C语言指针 与字符串的学习
  8. H5网站模板——前台和后台
  9. 快速排序 时间复杂度计算
  10. vue 文字转语音mp3_vue项目或网页上实现文字转换成语音播放功能