tk's blog
  • tk's blog Read Me
  • 算法相关
    • 数据结构
      • 【集训整理】 旋转treap模板
      • 二叉树及相关数据结构的java语言实现
      • 快乐树0x01:AVL树的java实现
      • 快乐树0x02 线段树实现(c++)
      • 链表的Java语言实现
    • 算法
      • DP的背包问题小结-java语言描述
      • 【集训整理】2-SAT问题 模板题
      • 【集训整理】Tarjan算法 模板题
      • 【集训整理】差分约束 模板题
      • 【集训整理】最近公共祖先LCA 模板题
      • 二分查找与二分答案-java实现
      • 动态规划-java语言练习一:暴力DP
      • 快速幂
      • 状态压缩DP-java描述
      • 差分
      • 乘法逆元
    • 题解
      • CFRound-GoodBye2022题解
  • java相关
    • Java与算法竞赛——注意事项摘录
    • java面向对象简要总结 一
    • java面向对象简要总结 三
    • java面向对象简要总结 二
  • 后端相关
    • Linux-Crontab命令
    • Spring Data JPA 使用方法
    • Spring集成Artemis实现JSM的异步消息传递
    • Spring使用自定义配置项
    • MIT6.824分布式系统Lab1.MapReduce笔记
    • MIT6.824分布式系统Lab2-Raft-A笔记
    • MIT6.824分布式系统Lab2-Raft-B笔记
  • 杂谈
    • 杂谈-关于2021
  • 杂项
    • c语言 scanf的返回值
    • 系统设计
  • 计科基础
    • 编译原理
      • 编译原理:词法分析笔记
    • CSAPP 第二章笔记
    • 计算机组成原理笔记
    • CSAPP Lab1. Datalab
    • CSAPP Lab2 Bomblab
  • C++每日一题
    • C++每日一题 Day 1 肥宅水
    • C++每日一题 Day 2 数字反转
    • C++每日一题 Day 3 理五的凡尔赛风气
    • C++每日一题 Day 4 我喜欢这个数
    • C++每日一题 Day 5 数字楼梯
    • C++每日一题 Day 6 插火把
    • C++每日一题 Day 7 贪吃蛇
    • C++每日一题 Day 8 蒙德最强战力
    • C++每日一题 Day 9 璃月七星选举
    • C每日一题 Day 2 肥宅水
    • C每日一题 Day 3 理五的凡尔赛风气
    • C语言每日一题 Day 1 荧妹好感队
由 GitBook 提供支持
在本页
  • 一、01背包
  • 题目
  • 分状态和转移方程
  • 二、完全背包
  • 题目
  • 分析
  • 优化
  • 三、多重背包
  • 题目
  • 分析
  1. 算法相关
  2. 算法

DP的背包问题小结-java语言描述


依然是复习以前学过的内容hhh

一、01背包

题目

一共有N件物品,第i(i从1开始)件物品的重量为w[i],价值为v[i]。在总重量不超过背包承载上限W的情况下,能够装入背包的最大价值是多少?

分状态和转移方程

显然变量为装入的物品和背包的质量,所求的目标是最大的价值。

因此设dp[i][j]来表示将前i件物品在j的限重下的价值最大值。

对于每个状态dp[i][j]有两种情况:

  1. 装入第i件物品(dp[i-1][j-w[i]] + v[i])

  2. 不装入 (dp[i-1][j])

故转移方程为:

dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])

二、完全背包

题目

同01背包类似,但每种物品可以取无限个。

分析

和01背包类似,我们设出同样的dp状态,dp[i][j]来表示将前i种物品在j的限重下的价值最大值。

还是分两种情况:

  1. 装入第i种物品,但和01背包不一样,这里装入一次以后还可以继续装入,所以应该转移到dp[i][j-w[i]] + v[i]而不是dp[i-1][j-w[i]] + v[i]。

  2. 不装入第i种物品(还是dp[i-1][j])

所以转移方程为:

dp[i][j] = max(dp[i][j], dp[i-1][j-w[i]] + v[i])

优化

这里可以做一个优化,可以通过滚动数组的方式,省去[i],压缩空间复杂度。

转移方程可改写为:dp[j] = max(dp[j], dp[j-w[i]] + v[i])

这里注意时间复杂度是不能被压缩的,而且这样写的前提是循环时j必须正向枚举,确保此时访问的dp[j-[i]]已经在本次循环中被计算到。

01背包也可以类似优化,只不过要逆向枚举,确保此时访问的dp[j-[i]]是上一次循环计算到的结果。

三、多重背包

题目

和完全背包不一样在于每种物品的数量是指定好的。一共有N种物品,第i(i从1开始)种物品的数量为n[i],重量为w[i],价值为v[i]。在总重量不超过背包承载上限W的情况下,能够装入背包的最大价值是多少?

分析

因为指定了特定种类的物品数就相当于指定了n个独立的物品,所以多重背包问题可以直接化为01背包问题解决,其时间复杂度也不高。

转移方程可参考01背包。具体就是把给定数量的物品都视为单独的01背包里的物品来处理。

参考

上一页算法下一页【集训整理】2-SAT问题 模板题

最后更新于2年前

动态规划之背包问题系列 - 知乎 (zhihu.com)