代码随想录刷题| 多重背包理论基础、背包问题的总结
创始人
2024-02-18 04:38:57
0

目录

多重背包理论基础

多重背包的问题

多重背包的解法

多重背包的代码

背包问题的总结

01背包

完全背包

多重背包


多重背包理论基础

多重背包的问题

  • 有N种物品和一个容量为V 的背包。第i种物品最多有Mi件可用,每件耗费的空间是Ci ,价值是Wi 。求解将哪些物品装入背包可使这些物品的耗费的空间 总和不超过背包容量,且价值总和最大

多重背包的解法

  • 多重背包问题可以使用01背包的思路去解决
  • 既然物品的数量是固定,就可以使用01背包,只不过其中的物品有重复
  • 假设现在有个背包如下:
  • 可以将这个多重背包转换成:
  • 这就可以看成一个01背包问题了 

多重背包的代码

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class MultiBagProblem {public static void main(String[] args) {// 物品信息/***          重量  价值  数值*  物品0     1    15    2*  物品1     3    20    3*  物品2     4    20    2*/List weight = new ArrayList<>(Arrays.asList(1,3,4));List value = new ArrayList<>(Arrays.asList(15,20,30));List nums = new ArrayList<>(Arrays.asList(2,3,3));// 背包信息int bagSize = 10;multiBag(weight,value,nums,bagSize);}/**** @param weight  物品的重量* @param value   物品的价值* @param nums    物品的数量* @param bagSize 背包的容量*/private static void multiBag(List weight,List value,List nums,int bagSize) {/*** 将物品展开*/// 先把物品展开,展开成一个物品只有一个for (int i = 0; i < nums.size(); i++) {while (nums.get(i) > 1) {weight.add(weight.get(i));value.add(value.get(i));nums.set(i , nums.get(i) - 1);   // 展开一个,原数量就减一}}/*** 按照01背包进行装包*/// 创建dp数组int[] dp = new int[bagSize+1];// 遍历更新dp数组for (int i = 0; i < weight.size(); i++) {  // 先对物品进行遍历for (int j = bagSize; j >= weight.get(i); j--) {  // 再对背包进行倒序遍历dp[j] = Math.max(dp[j],dp[j-weight.get(i)] + value.get(i));}// 打印dp数组System.out.println("物品" + i + "\t" + Arrays.toString(dp));}}
}

背包问题的总结

01背包

  • 01背包是重中之重
  • 01背包:有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大
  • 主要有以下几种问题:
    • 1、求物品装进背包中的最大价值(纯01背包)
      • 递推公式原理为:dp[ j ] = max( dp[ j ] , dp[ j - weight[ i ] ] + value[ i ]);
      • 对应的题目
        • 416.分割等和子集
        • 1049.最后一块石头的重量||
    • 2、求物品装满背包的方法数 
      • 递推公式原理为:dp[ j ] += dp[ j - weight[ i ] ]
      • 由于方法数是逐步积累的,所以初始化应该是dp[ 0 ] = 1
      • 对应的题目
        • 494.目标和
    • 3、求最终背包中的物品数
      • 递推公式原理为:dp[ j - weight[ i ] + 1]
      • 如果是求最大个数:就是dp[ j ] = max(dp[ j ],dp[ j - weight[ i ] ] + 1 );由于是求最大值,初始化时dp[0] = 0,其余的也为0。对应的题目有 474.一和零
      • 如果是求最小个数:就是dp[ j ] = min(dp[ j ],dp[ j - weight[ i ] ] + 1 );由于是求最小值,初始化时dp[0] = 0,其余的为MAX_VALUE。对应的题目有 322.零钱兑换

完全背包

  • 01背包的时候,为了使物品在向背包中添加的时候保证物品只添加一次,在遍历背包的时候使用倒序遍历
  • 那完全背包中的物品是可以被重复添加的,那么在遍历背包的时候使用正序遍历,就可以保证物品被多次添加
  • 主要有以下几种问题
    • 1、求物品装进背包中的最大价值(纯完全背包)
      • 递推公式原理为:dp[ j ] = max( dp[ j ] , dp[ j - weight[ i ] ] + value[ i ]);
    • 2、求物品装满背包的方法数 
      • 递推公式原理为:dp[ j ] += dp[ j - weight[ i ] ]
      • 由于方法数是逐步积累的,所以初始化应该是dp[ 0 ] = 1
      • 对应的题目
        • 518.零钱兑换|| —— 求组合数 —— 先遍历物品再遍历背包
        • 377.组合总和IV —— 求排列数 —— 先遍历背包再遍历物品
        • 70.爬楼梯 —— 求排列数 —— 先遍历背包再遍历物品
    • 3、求最终背包中的物品数
      • 递推公式原理为:dp[ j - weight[ i ] + 1]
      • 如果是求最小个数:就是dp[ j ] = min(dp[ j ],dp[ j - weight[ i ] ] + 1 );由于是求最小值,初始化时dp[0] = 0,其余的为MAX_VALUE
      • 对应的题目
        • 322.零钱兑换 
        • 279.完全平方数

多重背包

  • 多重背包的解决方案就是将多重背包转换成01背包进行处理
  • 原理上并没有什么难点,等遇到相应的题目再说

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...