背包问题

  • 七、背包问题
    • 1、01背包问题
      • 1.1 问题描述
      • 1.2 问题分析
      • 1.3 代码实现
      • 1.4 代码优化写法
    • 2、多重背包问题
      • 2.1 题目描述
      • 2.2 问题分析
      • 2.3 代码实现
      • 2.4 空间优化后的代码
    • 3、完全背包问题
      • 3.1 题目描述
      • 3.2 问题分析
      • 3.3 代码实现
      • 3.4优化后的代码

七、背包问题

1、01背包问题

1.1 问题描述

当前有N件物品和一个容积为V的背包。已知第i件物品的体积是Ci,价值是Wi。由于每种物品有且仅有一件,因此只能选择放或不放,我们称之为01背包问题。
现在你需要选出若干件物品,在它们的重量之和不超过V的条件下,使得价值总和尽可能大。

1.2 问题分析

对于01背包,先确定这个问题的状态。共有N个物品,背包总承重为V,那么可以根据物品和容量来确定一个状态。前i个物品,放在背包里,总重量不超过j的前提下,所获得的最大价值为dp[i][j]。

是否将第i个物品装入背包中,就是决策。为了使价值最大化,如果第i个物品放入背包后,总重量不超过限制且总价值比之前要大,那么就将第i个物品放入背包。根据这个逻辑写出转移方程:






1.3 代码实现

#include<iostream>
#include<cstring>
using namespace std;
int dp[21][1010];
int w[21],c[21]
int main(){int N,V;cin>>N>>V;//输入物品的个数N和背包体积for(int i=1;i<=N;i++){//输入N和物品的价值和体积cin>>w[i]>>c[i]; }for(int i=1;i<=N;i++){for(int j=0;j<=V;j++){if(j>=c[i]){dp[i][j]=max(dp[i-1][j-c[i]]+w[i],dp[i-1][j]);}else{dp[i][j]=dp[i-1][j];}}}cout<<dp[N][V]<<endl;return 0;
}

1.4 代码优化写法

#include<iostream>
#include<cstring>
using namespace std;
int dp[1010];
int w[21],c[21]
int main(){int N,V;cin>>N>>V;//输入物品的个数N和背包体积Vfor(int i=1;i<=N;i++){//输入N个物体各自的价值和体积cin>>w[i]>>c[i];  }for(int i=1;i<=N;i++){//循环枚举每个物体for(int j=0;j>=c[i];j--){//循环枚举背包体积,从大到小排序以保证更新顺序正确dp[j]=max(dp[j-c[i]]+w[i],dp[j]);}}cout<<dp[V]<<endl;return 0;
}

2、多重背包问题

2.1 题目描述

有N种物品,第i种物品的体积是c[i],价值是w[i],每种物品的数量都是有限的,为n[i]。现有容量为V的背包,请你放入若干物品,在总体积不超过V的条件下,使总价值尽可能大。

2.2 问题分析

2.3 代码实现

#include<iostream>
#include<cstring>
using namespace std;
int dp[21][1010];
int w[21],c[21],n[21];
int main()
{int N,V;cin>>N>>V;for(int i=1;i<=N;++i)cin>>w[i]>>c[i]>>n[i];//输入N个物体各自的价值、体积和个数for(int i=1;i<=N;++i)//枚举第i个物品选出的个数为k{for(int j=0;j<=V;++j)//循环枚举每个物体{for(int k=0;k<=n[i];++k){if(j>=c[i]*k)dp[i][j]=max(dp[i-1][j-c[i]*k]+w[i]*k,dp[i][j]);}}}cout<<dp[N][V]<<endl;return 0;
}

2.4 空间优化后的代码

#include<iostream>
#include<cstring>
using namespace std;
int dp[1010];
int w[21],c[21],n[21];
int main()
{int N,V;cin>>N>>V;for(int i=1;i<=N;++i)cin>>w[i]>>c[i]>>n[i];for(int i=1;i<=N;++i){for(int j=0;j>=0;j--){for(int k=0;k<=n[i];++k){if(j>=c[i]*k)dp[j]=max(dp[j-c[i]*k]+w[i]*k,dp[j]);}}}cout<<dp[V]<<endl;return 0;
}

3、完全背包问题

3.1 题目描述

当前有N种物品,第i种物品的体积是c[i],价值是w[i]。
每种物品的数量都是无限的,可以任意选择若干件。
现有容量为V的背包,请你放入若干物品,在总体积不超过V的条件下,使总价值尽可能大。
与01背包问题的区别就是物品有无限多个.

3.2 问题分析

3.3 代码实现

#include<iostream>
#include<cstring>
using namespace std;
int dp[21][1010];
int w[21],c[21];
int main()
{int N,V;cin>>N>>V;for(int i=1;i<=N;++i)//输入N个物体各自的价值和体积cin>>w[i]>>c[i];for(int i=1;i<=N;++i)//由状态转移方程可得{for(int j=0;j<=V;++j){if(j>=c[i])dp[i][j]=max(dp[i][j-c[i]]+w[i],dp[i-1][j]);else dp[i][j]=dp[i-1][j];}}cout<<dp[N][V]<<endl;return 0;
}

3.4优化后的代码

#include<iostream>
#include<cstring>
using namespace std;
int dp[1010];
int w[21],c[21];
int main()
{int N,V;cin>>N>>V;for(int i=1;i<=N;++i)cin>>w[i]>>c[i];for(int i=1;i<=N;++i)//循环枚举每个物品{for(int j=c[i];j<=V;++j)//循环枚举背包体积,体积按照从小到大的顺序枚举,保证更新的顺序正确。{dp[j]=max(dp[j-c[i]]+w[i],dp[j]);}}cout<<dp[V]<<endl;return 0;
}

LQ训练营(C++)学习笔记_背包问题相关推荐

  1. LQ训练营(C++)学习笔记_常见动态规划模型

    常见动态规划模型 六.常见动态规划模型 1.最大字段和 1.1 概念描述 1.2动态规划算法分析 1.3 代码实现 2.最长上升子序列(LIS) 2.1 概念描述 2.2 算法分析 2.3 代码实现 ...

  2. LQ训练营(C++)学习笔记_动态规划入门

    动态规划入门 五.动态规划入门 1.动态介绍 1.1动态规划基本思路 1.2 动态规划基本概念 1.2.1 阶段 1.2.2 状态 1.2.3 决策 1.2.4 状态转移方程 1.2.5 策略 1.3 ...

  3. LQ训练营(C++)学习笔记_广度优先搜索

    这里写目录标题 四.广度优先搜索 1.队列的概念 2.小朋友报数问题 2.1 问题描述 2.2 代码实现 3.广度优先搜索概念 4.走迷宫问题 4.1 问题描述 4.2 代码实现 5.过河卒问题 5. ...

  4. LQ训练营(C++)学习笔记_深度优先搜索

    深度优先搜索 三.深度优先搜索 1.普通深度优先搜索 1.1 迷宫问题描述 1.2 代码实现 2.抽象深度优先搜索问题 2.1 和为K问题 2.1.1 问题描述 2.1.2 解题思路 2.1.3 代码 ...

  5. LQ训练营(C++)学习笔记_枚举算法

    枚举算法 一.枚举算法 1.枚举的概念 2.枚举的题目特点 3.问题描述 4.代码实现 一.枚举算法 1.枚举的概念 枚举就是根据提出的问题,列出该问题所有可能的解,并在逐一列出的过程中,检验每个可能 ...

  6. LQ训练营(C++)学习笔记_栈与递归

    栈与递归 二.栈与递归 1.栈的概念 2.代码实现栈的数据结构 3.栈stack< T >的方法总结 4.火车出入站问题 5.递归的概念 6.递归方法求n的阶乘 7.汉诺塔问题 二.栈与递 ...

  7. oracle11g中用asmlib配置磁盘组,ASM学习笔记_配置ASMLIB磁盘组

    ASM学习笔记_配置ASMLIB磁盘组 目录 1 ASMLIB Introduction 2 虚拟机添加一个共享磁盘(块设备) 3 下载,安装ASMLIB 4 配置,使用ASMLib 磁盘组 #### ...

  8. MySQL学习笔记_关于MySQL的字符类型VARCHAR长度知识总结

    MySQL学习笔记_关于MySQL的字符类型VARCHAR长度知识总结 一.VARCHAR存储和行长度限制 1.VARCHAR(N)中,N指的是字符的长度,VARCHAR类型最大支持65535,指的是 ...

  9. 馒头何瑫写作训练营的学习笔记总结

    文章目录 一.确定写作主题 (一)学习引导 (2)确定写作主题的方法 (3)如何提高故事的传播性 (4)故事应该聚焦的点 (5)动笔之前需思考的问题 二.获取写作素材 (一)获取写作素材的方法 (2) ...

最新文章

  1. sklearn解决回归问题
  2. 如何在React Native中记录日志?
  3. flutter中list相关操作汇总(有这一篇就够啦)
  4. error LNK2026: 模块对于 SAFESEH 映像是不安全的
  5. python特殊符号请求参数_python-参数化-(3)(excel中特殊标识字符替换数据)
  6. givemesomecredit数据_你是如何走上数据分析之路的?
  7. 第三次学JAVA再学不好就吃翔(part93)--LinkedHashMap
  8. 树莓派3B上部署运行.net core 2程序
  9. apache karaf_未来是Apache Karaf上的微服务架构
  10. 百度云盘照片导入华为相册里_必须知道的相册管理工具
  11. ARM S3C2410硬件手册重点
  12. 现实问题从数学化到离散化再到程序化
  13. 移植最新版libmemcached到VC++的艰苦历程和经验总结(上)
  14. openwrt编译qca驱动不成功。gcc -isystem问题。
  15. Java常量池详解:字符串常量池、Class常量池、运行时常量池 三者关系
  16. Unity TimeLine学习笔记
  17. 于的繁体字有几种写法_“龙”的繁体字有几种写法?
  18. 二自由度云台扫描算法_控制算法手记-二自由度控制器
  19. TIA博途中分布式IO ET200SP的使用方法
  20. 记码农十周年(20110214--20210214)

热门文章

  1. foreach jdk8 递归_[Java 8] (8) Lambda表达式对递归的优化(上) - 使用尾递归 .
  2. openrowset excel 科学计数_txt的数据导入excel中身份证或银行卡显示成科学计数如何解决...
  3. osg渲染到纹理技术(二)
  4. 计算机科学与教育信息化国际会议,A Courses Ontology System for Computer Science Education...
  5. vc连接mysql 查询_vc连接数据库中查询代码如何写呀 急急急!!!!!!
  6. Swift调用第三方OC项目
  7. 10月13日学习内容整理:线程,创建线程(threading模块),守护线程,GIL(全局解释器互斥锁)...
  8. android R.id.转化为view
  9. BeanShell快速入门---Java应用
  10. spring security只要熟悉每个filter的作用和顺序