参考(都有些错误):https://github.com/guanjunjian/Interview-Summary/blob/master/notes/algorithms/%E7%BB%8F%E5%85%B8%E7%AE%97%E6%B3%95/01%E8%83%8C%E5%8C%85.mdhttps://blog.csdn.net/na_beginning/article/details/62884939
#include <iostream>
#include <sstream>
#include <vector>
#include <string>using namespace std;/*
01背包问题 每个物品仅一个
状态转移公式:F[i][j] = F[i - 1][j] 和 F[i - 1][j - W[i]] + V[i] 大的那个值
C背包总重量
W每个物品重量
V每个物品价值
n物品总数
inp具有最大价值时,标记哪个物品在包中
返回最大价值
*/
int packages(int C, vector<int> &W, vector<int> &V, int n, vector<int> &inp)
{vector<vector<int> > F(n, vector<int>(C + 1));//F[i][j]记录背包可用重量为j时,前i个物品的最大价值for (int i = 0; i < n; i++)//初始化表格
    {for (int j = 0; j < F[0].size(); j++)F[i][j] = 0;}for (int j = 1; j < F[0].size(); j++)//初始化第一行F[0][j] = (j < W[0]) ? 0 : V[0];//可用重量j大于物品重量,则装入该物品,加上该物品价值for (int i = 1; i < n; i++){for (int j = 1; j < F[0].size(); j++){if (j < W[i])F[i][j] = F[i - 1][j];//装不下该物品elseF[i][j] = (F[i - 1][j] < F[i - 1][j - W[i]] + V[i]) ? F[i - 1][j - W[i]] + V[i] : F[i - 1][j];//可装下该物品。状态转移方程
        }}int result = F[n - 1][F[0].size() - 1];//最大价值//inp标记哪些物品在包中int j = C;for (int i = n-1; i >0 ; i--)//i不可为0,否则F[i-1]越界
    {if (j>W[i] && F[i][j] == F[i - 1][j - W[i]] + V[i])//注意需要j>W[i]
        {inp[i] = 1;j -= W[i];}}if (F[0][j] > 0)//如果背包还可装下,则包含第一个物品inp[0] = 1;//输出动态规划数组for (int i = 0; i < n; i++){for (int j = 0; j < F[0].size(); j++)cout << F[i][j] << " ";cout << endl;}return result;
}/*
01背包问题 滚动数组优化动态规划的空间
原空间OnC,先空间O2C,但是无法输出有哪些物品在包中
*/
int packages_good(int C, vector<int> &W, vector<int> &V, int n)
{vector<vector<int> > F(2, vector<int>(C + 1));//F[i][j]记录背包可用重量为j时,前i个物品的最大价值for (int i = 0; i < 2; i++)//初始化表格
    {for (int j = 0; j < F[0].size(); j++)F[i][j] = 0;}for (int j = 1; j < F[0].size(); j++)//初始化第一行F[0][j] = (j < W[0]) ? 0 : V[0];//可用重量j大于物品重量,则装入该物品,加上该物品价值int k = 0;for (int i = 1; i < n; i++){k = i & 1;//滚动for (int j = 1; j < F[0].size(); j++){if (j < W[i])F[k][j] = F[k ^ 1][j];//装不下该物品elseF[k][j] = (F[k ^ 1][j] < F[k ^ 1][j - W[i]] + V[i]) ? F[k ^ 1][j - W[i]] + V[i] : F[k ^ 1][j];//可装下该物品
        }}return F[k][F[0].size() - 1];//最大价值
}/*
完全背包 每个物品不限制数量
状态转移公式:F[i][j] = F[i - 1][j] 和 F[i][j - W[i]] + V[i] 大的那个值,标记哪些物品在包中也改变
注意是F[i][j - W[i]] + V[i]
也可优化空间
*/
int packages_full(int C, vector<int> &W, vector<int> &V, int n, vector<int> &inp)
{vector<vector<int> > F(n, vector<int>(C + 1));//F[i][j]记录背包可用重量为j时,前i个物品的最大价值for (int i = 0; i < n; i++)//初始化表格
    {for (int j = 0; j < F[0].size(); j++)F[i][j] = 0;}for (int j = 1; j < F[0].size(); j++)//初始化第一行F[0][j] = (j < W[0]) ? 0 : ((j/W[0])*V[0]);//每个物品不止一个for (int i = 1; i < n; i++){for (int j = 1; j < F[0].size(); j++){if (j < W[i])F[i][j] = F[i - 1][j];//装不下该物品elseF[i][j] = (F[i - 1][j] < F[i][j - W[i]] + V[i]) ? F[i][j - W[i]] + V[i] : F[i - 1][j];//可装下该物品。状态转移方程
        }}int result = F[n - 1][F[0].size() - 1];//最大价值//inp标记哪些物品在包中int j = C;int i = n - 1;while (i){while(j && j > W[i] && F[i][j] == F[i][j - W[i]] + V[i]) //如果包含该物品,则一直循环看包含几个该物品
        {inp[i]++;j -= W[i];}i--;//不包含该物品,则跳到下一个物品
    }//输出动态规划数组for (int i = 0; i < n; i++){for (int j = 0; j < F[0].size(); j++)cout << F[i][j] << " ";cout << endl;}return result;
}/*
多重背包 每个物品有数量限制
*/
int packages_multi(int C, vector<int> &W, vector<int> &V, int n, vector<int> &inp, vector<int> &N)//N会被修改
{vector<vector<int> > F(n, vector<int>(C + 1));//F[i][j]记录背包可用重量为j时,前i个物品的最大价值for (int i = 0; i < n; i++)//初始化表格
    {for (int j = 0; j < F[0].size(); j++)F[i][j] = 0;}for (int j = 1; j < F[0].size(); j++)//初始化第一行,每个物品有对应数量N限制
    {int count = (N[0] > j / W[0]) ? j / W[0] : N[0];//可用空间为j时,可以放多少个当前物品,min{可放入数量,物品数量}F[0][j] = (j < W[0]) ? 0 : (count*V[0]);}for (int i = 1; i < n; i++){for (int j = 1; j < F[0].size(); j++){if (j < W[i])F[i][j] = F[i - 1][j];//装不下该物品else{int count = (N[i] > j / W[i]) ? j / W[i] : N[i];F[i][j] = F[i - 1][j];//不放当前物品for (int k = 1; k <= count; k++)//看放入多少个当前物品可以让F[i][j]最大
                {int tmp = F[i - 1][j - k * W[i]] + k * V[i];//放入k个当前物品if (tmp > F[i][j])F[i][j] = tmp;}}}}int result = F[n - 1][F[0].size() - 1];//最大价值cout << result << endl;//inp标记哪些物品在包中int j = C;int i = n - 1;while (i){while (j && N[i] && j > W[i] && F[i][j] == F[i][j - W[i]] + V[i]) //如果包含该物品,则一直循环看包含几个该物品
        {inp[i]++;j -= W[i];--N[i];}i--;//不包含该物品,则跳到下一个物品
    }//输出动态规划数组for (int i = 0; i < n; i++){for (int j = 0; j < F[0].size(); j++)cout << F[i][j] << " ";cout << endl;}return result;
}int main() {vector<int> W{ 4,5,6,2,2 };vector<int> V{ 6,4,5,3,6 };int C = 9;int n = W.size();vector<int> inp(n, 0);//标记是否在包中cout << "1、01背包最大总价值:" << packages(C, W, V, n, inp) << endl;cout << "在背包中的物品编号: ";for (int i = 0; i < inp.size(); i++){if (inp[i] == 1)cout << i << " ";}cout << endl;cout << "2、01背包滚动数组优化最大总价值,无法输出有哪些物品在背包中:" << packages_good(C, W, V, n) << endl;cout << endl;vector<int> inp1(n, 0);//标记是否在包中cout << "3、完全背包最大总价值:" << packages_full(C, W, V, n, inp1) << endl;cout << "输出在背包中物品: ";for (int i = 0; i < inp1.size(); i++){cout << inp1[i] << " ";}cout << endl;cout << endl;vector<int> N{ 1,2,2,2,4 };//每个物品数量vector<int> inp2(n, 0);//标记是否在包中cout << "4、多重背包最大总价值:" << packages_multi(C, W, V, n, inp2, N) << endl;cout << "输出在背包中物品: ";for (int i = 0; i < inp2.size(); i++){cout << inp2[i] << " ";}cout << endl;return 0;
}

转载于:https://www.cnblogs.com/beixiaobei/p/10914211.html

01背包、完全背包、多重背包相关推荐

  1. 背包问题-【01背包】【完全背包】【多重背包】【多限定条件背包】

    背包问题 给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高. 可参考https://www.cnblogs.com/-guz/p/9866118.h ...

  2. 小明打联盟 牛客(背包dp,多重背包)

    链接:https://ac.nowcoder.com/acm/problem/14553 来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放 ...

  3. 01背包模板、全然背包 and 多重背包(模板)

    转载请注明出处:http://blog.csdn.net/u012860063 贴一个自觉得解说不错的链接:http://www.cppblog.com/tanky-woo/archive/2010/ ...

  4. 【qduoj - 142】 多重背包(0-1背包的另类处理,dp)

    题干: ycb的ACM进阶之路 Description ycb是个天资聪颖的孩子,他的梦想是成为世界上最伟大的ACMer.为此,他想拜附近最有威望的dalao为师.dalao为了判断他的资质,给他出了 ...

  5. 01背包模板、完全背包 and 多重背包

    转载请注明出处:http://blog.csdn.net/u012860063 讲解链接:http://www.cppblog.com/tanky-woo/archive/2010/07/31/121 ...

  6. 【python】一篇讲透背包问题(01背包 完全背包 多重背包 二维费用背包)

    面对背包问题,有一个很重要的方程式:状态转移方程式 所以每一种背包问题我都会给出状态转移方程式 #01背包 什么是01背包型问题? 先给大家感受一下01背包型问题: 给定n种物品和一背包.物品i的重量 ...

  7. c++ 多重背包状态转移方程_【模板】各种背包问题amp;讲解

    [模板]各种背包问题&讲解  背包问题集合 一般来说,动态规划(DP)都是初学者最难闯过的一关,而在这里详细解说动态规划的一种经典题型:背包问题. 这里介绍的背包分为以下几种:01背包,完全背 ...

  8. (step3.3) hdu 1059(Dividing——多重背包)

    题目大意:分别给出价值为1~6的石头的数量.问能否将这些石头等价值平分... 解题思路:多重背包 1)多重背包的典型描述是这样的:给出n种物品,背包的容量为V.每种物品的可用数量为num[i],所占体 ...

  9. 1919: kirito's 星爆气流斩 多重背包

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

  10. 最少硬币问题----多重背包

    问题描述: 设有n 种不同面值的硬币,各硬币的面值存于数组T[1:n ]中.现要用这些面值的硬币来找钱.可以使用的各种面值的硬币个数存于数组Coins[1:n ]中.对任意钱数0≤m≤20001,设计 ...

最新文章

  1. 1062 Talent and Virtue
  2. c语言流程图图裂代表的意义,程序流程图的意义
  3. python csv 模块的使用
  4. log4j配置日志系统成功 (转)
  5. 初学linux系统代码,linux初学者-系统日志(二)(示例代码)
  6. 【转】国密算法sm4 CBC模式加解密
  7. linux3.x内核实时性改进,linux 3.x内核优化指南
  8. 支持向量机的基本思想_支持向量机的分类思想
  9. LinkedList源码阅读笔记(1.8)
  10. Java classLoader【转】
  11. springboot 多数据源_SpringBoot整合多数据源的巨坑一
  12. 抢先一步 华为将于7月26日发布首款5G智能手机
  13. VS2008环境下开发的某些程序在其他机器运行提示“由于应用程序配置不正确,应用程序未能启动”的问题(IIS)...
  14. WdatePicker—WdatePicker日历控件使用方法
  15. mysql 、慢查询、到底如何玩
  16. 面试题之get和post的区别
  17. Ifconfig网络配置工具详解(from fixdown.com)
  18. 数据特征分析 正态性检验
  19. <C++>初识STL —— 标准模板库
  20. 【EI会议推荐】第四届机器人、智能控制与人工智能国际学术会议(RICAI 2022)

热门文章

  1. linux进程和计划任务,linux进程和计划任务
  2. 一个路径下挂载(匹配)多个子组件
  3. android无感刷新下拉分页,GitHub - TakWolf/Android-RefreshAndLoadMore-Demo: 一种简单的并且优雅的方式实现下拉刷新和加载更多的分页效果。...
  4. python中ndarray对象实例化_Python数据分析之Numpy学习 2——NumPy 基础 ndarray对象
  5. python loadtxt_Python 数据科学入门2:Matplotlib
  6. pycharm常用快捷键详解,让你编程 事半功倍。
  7. 洛谷 P4016 负载平衡问题 【最小费用最大流】
  8. 5专题总结-数据结构
  9. IT基础架构规划方案二(计算机系统与机房规划规划)
  10. ie6 7下 relative absolute无法冲破的等级问题解决办法