01背包问题

    朴素版:(二维数组)

状态表示: dp[i][j]:从前i个物品中选择(每个物品只能选0或1个)且总体积不超过j的集合的最大价值,则dp[n][m]就是最终答案(n:物品数量,m:最大体积)

状态计算: dp[i][j] = max ( dp[i-1][j] , dp[i-1][j-vi]+wi )  // 由含i和不含i两个子集合计算而来(vi:物品体积,wi:物品价值)

核心代码:

int n, m; // n:物品数量, m:最大体积
int v[N], w[N], dp[N][M]; void keyCode()
{
for(int i = 1; i <= n; i++)
for(int j = 0; j <= m; j++)
{
dp[i][j] = dp[i-1][j];
if(v[i] >= j) dp[i][j] = max(dp[i][j], dp[i-1][j-v[i]] + w[i]);
}
}

空间优化版:(滚动数组,二维数组优化至一维)

  状态表示:dp[j]:在外循环的第i层时,表示从前i个物品中选择(每个物品只能选0或1个)且总体积不超过j的集合的最大价值,n层循环后,dp[m]就是最终答案

  状态计算:dp[j] = max ( dp[j] , dp[j-vi]+wi )  // 由含i和不含i两个子集合计算而来

  核心代码:

int n, m; // n:物品数量, m:最大体积
int v[N], w[N], dp[N]; void keyCode()
{
for(int i = 1; i <= n; i++)
// 反向遍历, 否则dp[j-v[i]]可能为dp[i][j-v[i]](用更新后的值来更新导致出错)
for(int j = m; j >= v[i]; j--)
dp[j] = max(dp[j], dp[j-v[i]] + w[i]); }

完全背包问题

朴素版:(二维数组)

  状态表示:dp[i][j]:从前i种物品中选择(每种物品可以任选个数)且总体积不超过j的集合的最大价值,则dp[n][m]就是最终答案

  状态计算:dp[i][j] = max ( dp[i-1][j] , dp[i][j-vi]+wi )

    证明:dp[i][j] = max ( dp[i-1][j] , dp[i-1][j-vi]+wi , dp[i-1][j-2vi]+2wi , dp[i-1][j-3vi]+3wi , ...... )

       dp[i][j-vi] = max (               dp[i-1][j-vi] ,      dp[i-1][j-2vi]+wi ,   dp[i-1][j-3vi]+2wi ,  ...... )

       Thus,dp[i][j-vi]+wi = max ( dp[i-1][j-vi]+wi , dp[i-1][j-2vi]+2wi , dp[i-1][j-3vi]+3wi ,  ...... )

       Thus,dp[i][j] = max ( dp[i-1][j] , dp[i][j-vi]+wi )

  核心代码:

int n, m; // n:物品数量, m:最大体积
int v[N], w[N], dp[N][M]; void keyCode()
{
for(int i = 1; i <= n; i++)
for(int j = 0; j <= m; j++)
{
dp[i][j] = dp[i-1][j];
if(j >= v[i]) dp[i][j] = max(dp[i][j], dp[i][j-v[i]] + w[i]);
}
}

空间优化版:(滚动数组,二维数组优化至一维)

  状态表示:dp[j]:在外循环的第i层时,表示从前i种物品中选择(每种物品可以任选个数)且总体积不超过j的集合的最大价值,n层循环后,dp[m]就是最终答案

  状态计算:dp[j] = max ( dp[j] , dp[j-vi]+wi )  // 由含i和不含i两个子集合计算而来

  核心代码:

int n, m; // n:物品数量, m:最大体积
int v[N], w[N], dp[N]; void keyCode()
{
for(int i = 1; i <= n; i++)
// 正向遍历, 使得dp[j-v[i]]为dp[i][j-v[i]]
for(int j = v[i]; j <= m; j++)
dp[j] = max(dp[j], dp[j-v[i]] + w[i]); }

多重背包问题

朴素版:(二维数组+三重循环)

  状态表示:dp[i][j]:从前i种物品中选择(每种物品最多选择si个)且总体积不超过j的集合的最大价值,则dp[n][m]就是最终答案

  状态计算:dp[i][j] = max ( dp[i-1][j],dp[i-1][j-v]+w,dp[i-1][j-2v]+2w,...,dp[i-1][j-sv]+sw )

  核心代码:

int n, m; // n:物品数量, m:最大体积
int v[N], w[N], s[S];
int dp[N][M]; void keyCode()
{
for(int i = 1; i <= n; i++)
for(int j = 0; j <= m; j++)
for(int k = 0; k <= s[i] && k * v[i] <= j; k++)
dp[i][j] = max(dp[i][j], dp[i-1][j-k*v[i]] + k*w[i]);
}

优化版:(一维数组+二重循环)

  二进制优化:对于每种物品,将其按2的次幂大小拆分合并,如s[i]=12时,方案为:第1个物品合并,第2~3个物品合并,第4~7个物品合并,第8~12个物品合并(1,2,4,5)。这样,就将多重背包问题转化成01背包问题

  状态表示:dp[j]:在外循环的第i层时,表示从前i个物品中选择(每个物品只能选0或1个)且总体积不超过j的集合的最大价值,n层循环后(n为问题转化后的新n),dp[m]就是最终答案

  状态计算:dp[j] = max ( dp[j] , dp[j-vi]+wi )

  核心代码:

int n, m;
int v[N], w[N], dp[M]; // N:maxn * logmaxs void keyCode()
{
int cnt = 0;
for(int i = 1; i <= n; i++)
{
int a, b, s; // vi, wi, si
cin >> a >> b >> s;
int p = 1;
while(p <= s)
{
cnt ++;
v[cnt] = a * p, w[cnt] = b * p;
s -= p, p *= 2;
}
if(s > 0)
{
cnt ++;
v[cnt] = a * s, w[cnt] = b * s;
}
}
n = cnt; // n --> 问题转化后的新n
for(int i = 1; i <= n; i++)
for(int j = m; j >= v[i]; j--) // 反向遍历
dp[j] = max(dp[j], dp[j-v[i]] + w[i]);
}

 

分组背包问题

朴素版:(二维数组)

  状态表示:dp[i][j]:从前i组物品中选择(每组物品中只能选择0或1个)且总体积不超过j的集合的最大价值,则dp[n][m]就是最终答案

  状态计算:dp[i][j] = max ( dp[i-1][j],dp[i-1][j-vi,1]+wi,1,dp[i-1][j-vi,2]+wi,2,dp[i-1][j-vi,3]+wi,3,... )

  核心代码:

int n, m; // n:物品数量, m:最大体积
int s[N], v[N][S], w[N][S];
int dp[N][M]; void keyCode()
{
for(int i = 1; i <= n; i++)
{
for(int j = 0; j <= m; j++)
{
dp[i][j] = dp[i-1][j];
for(int k = 1; k <= s[i]; k++)
if(v[i][k] <= j)
dp[i][j] = max(dp[i][j], dp[i-1][j-v[i][k]] + w[i][k]);
}
}
}

    空间优化版:(滚动数组,二维数组优化至一维)

int n, m; // n:物品数量, m:最大体积
int s[N], v[N][S], w[N][S];
int dp[M]; void keyCode()
{
for(int i = 1; i <= n; i++)
{
for(int j = m; j >= 0; j--) // 反向遍历
{
for(int k = 1; k <= s[i]; k++)
if(v[i][k] <= j)
dp[j] = max(dp[j], dp[j-v[i][k]] + w[i][k]);
}
}
}

背包问题学习笔记 / Dynamic Programming(updating)的更多相关文章

  1. angular2 学习笔记 ( Dynamic Component 动态组件)

    更新 2018-02-07 详细讲一下 TemplateRef 和 ViewContainerRef 的插入 refer : https://segmentfault.com/a/1190000008 ...

  2. DP背包问题学习笔记及系列练习题

    01 背包: 01背包:在M件物品中取出若干件物品放到背包中,每件物品对应的体积v1,v2,v3,....对应的价值为w1,w2,w3,,,,,每件物品最多拿一件. 和很多DP题一样,对于每一个物品, ...

  3. 动态规划 Dynamic Programming 学习笔记

    文章以 CC-BY-SA 方式共享,此说明高于本站内其他说明. 本文尚未完工,但内容足够丰富,故提前发布. 内容包含大量 \(\LaTeX\) 公式,渲染可能需要一些时间,请耐心等待渲染(约 5s). ...

  4. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十八章:立方体贴图

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十八章:立方体贴图 代码工程地址: https://github.c ...

  5. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十三章:计算着色器(The Compute Shader)

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十三章:计算着色器(The Compute Shader) 代码工程 ...

  6. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二)

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第七章:在Direct3D中绘制(二) 代码工程地址: https:/ ...

  7. Dynamic CRM 2013学习笔记 系列汇总

    这里列出所有 Dynamic CRM 2013学习笔记 系列文章,方便大家查阅.有任何建议.意见.需要,欢迎大家提交评论一起讨论. 本文原文地址: Dynamic CRM 2013学习笔记 系列汇总 ...

  8. IOS学习笔记之关键词@dynamic

    IOS学习笔记之关键词@dynamic @dynamic这个关键词,通常是用不到的. 它与@synthesize的区别在于: 使用@synthesize编译器会确实的产生getter和setter方法 ...

  9. Dynamic CRM 2013学习笔记(一)插件输入实体参数解析

      1. 问题描述 最近新建了一个post事件的插件,传入的参数处理如下: 1: if (context.InputParameters.Contains("Target") &a ...

随机推荐

  1. SpringBoot如何优雅关闭(SpringBoot2.3&Spring Boot2.2)

    SpringBoot如何优雅关闭(SpringBoot2.3&Spring Boot2.2) 优雅停止&暴力停止 暴力停止:像日常开发过程中,测试区或者本地开发时,我们并不会考虑项目关 ...

  2. CSS加载不会阻塞DOM树解析

    1.css的加载不会阻塞DOM树解析. 1).css加载不会阻塞DOM树的解析: 2).css加载会阻塞DOM树渲染: 先把DOM树结构先解析完,等CSS加载完后根据最终样式渲染DOM树,免了css加 ...

  3. ELF文件结构

    ELF文件结构 ELF文件的全称是Executable and Linkable Format,直译为"可执行可链接格式",包括目标文件(.o).可执行文件(可以直接运行).静态链 ...

  4. 百万数据 mysql count(*)优化

    一.故事背景有一张 500w 左右的表做 select count(*) 速度特别慢. 二.原 SQL 分析Server version: 5.7.24-log MySQL Community Ser ...

  5. 图文详解 HDFS 的工作机制及其原理

    大家好,我是大D. 今天开始给大家分享关于大数据入门技术栈--Hadoop的学习内容. 初识 Hadoop 为了解决大数据中海量数据的存储与计算问题,Hadoop 提供了一套分布式系统基础架构,核心内 ...

  6. Android7.1.2 源码编译并烧写Nexus5X

    1.环境配置 Ubuntu18.04 openJDK1.8 Python2.7 2.更新Ubuntu镜像源 编辑/etc/apt/source.list,替换为以下内容 deb http://mirr ...

  7. 面试官:Dubbo是什么,他有什么特性?

    哈喽!大家好,我是小奇,一位热爱分享的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 书接上回,今天还是过周末,虽然 ...

  8. DataX异构数据源离线同步工具json文件配置说明

    DataX 是阿里开源的一个异构数据源离线同步工具,致力于实现包括关系型数据库(MySQL.Oracle等).HDFS.Hive.ODPS.HBase.FTP等各种异构数据源之间稳定高效的数据同步功能 ...

  9. Servlet的本质

    简介:Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层. 功能:使 ...

  10. (干货)基于 veImageX 搭建海报生成平台 -- 附源码

    前言 618 年中促销即将来临,很多公司都会通过海报来宣传自己的促销方案,通常情况下海报由设计团队基于 PS.Sketch 等工具创作,后期若想替换海报文案.商品列表等内容则需打开原工程进行二次创作, ...