当前位置: 首页 > article >正文

算法刷题|139.单词拆分、多重背包

单词拆分

题目:给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。

注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

思路:字符串s就是我们的背包,wordDict就是物品,我们要从物品中选出有序的字符串拼接成目标字符串s

  • dp[i]的含义:对于长度为i的字符串,能否在字典中找出字符串拼接成目标的字符串s的值为dp[i]
  • 递推公式:if(wordDict.contains(substring(j,i) && dp[j]) dp[i] = true
    单词拆分
  • dp数组的初始化:dp[0] = true
  • 遍历顺序:因为求排列,所有是先遍历背包,后遍历物品
  • 打印dp数组
class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        // dp[i]表示:字符串长度为i对字符串 能否拼接出s的值为dp[i]
        boolean[] dp = new boolean[s.length()+1];
        // 初始化
        dp[0] = true;
        for(int i = 1;i<=s.length();i++){// 背包
            for(int j = 0;j<i;j++){// 物品 这里为什么是 j<i,因为字符串的长度就是i,不能大于i,大于i了就没有一样
                String str = s.substring(j,i);
                if(wordDict.contains(str) && dp[j]){
                    dp[i] = true;
                }
            }
        }
        return dp[s.length()];
    }
}

多重背包

什么是多重背包?
就是在0-1背包的基础上增加了物品数量的限制,也就是说,现在有容量为bagSize的背包容量和一些物品,这个物品的属性有重量、价值和数量,然后求背包能够装的最大价值是多少

思路:我们可以把物品数量大于1的物品展开,也就是在增加一个相同的重量和价值的物品,这样当前的问题也就变成了0-1背包的问题了

多重背包

  • dp[j]的含义:背包容量为i的最大价值为dp[j]
  • 递推公式:dp[j] = Math.max(dp[j],dp[j-weigth[i]]+value[i])
  • dp数组初始化:dp[0]=0
  • 遍历顺序:先背包,后物品
  • 打印dp数组
public static void main(String[] args) {
        Test test = new Test();
        List<Integer> weight = new ArrayList<>(Arrays.asList(1, 3, 4));
        List<Integer> value = new ArrayList<>(Arrays.asList(15, 20, 30));
        List<Integer> nums = new ArrayList<>(Arrays.asList(2, 3, 2));
        System.out.println(test.multiPack(weight, value, nums, 10));
    }

    /**
     * 多重背包
     *
     * @param weight  物品重量
     * @param value   物品价值
     * @param nums    物品数量
     * @param bagSize 背包容量
     * @return 背包能够装的最大价值
     */
    private int multiPack(List<Integer> weight, List<Integer> value, List<Integer> 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);
            }
        }
        // 0-1背包
        int[] dp = new int[bagSize + 1];
        dp[0] = 0;
        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));
            }
        }
        return dp[bagSize];
    }

还有一种方式就是在0-1背包的基础上增加遍历个数

public static void main(String[] args) {
        Test test = new Test();
        List<Integer> weight = new ArrayList<>(Arrays.asList(1, 3, 4));
        List<Integer> value = new ArrayList<>(Arrays.asList(15, 20, 30));
        List<Integer> nums = new ArrayList<>(Arrays.asList(2, 3, 2));
        System.out.println(test.multiPack(weight, value, nums, 10));
    }

    /**
     * 多重背包
     *
     * @param weight  物品重量
     * @param value   物品价值
     * @param nums    物品数量
     * @param bagSize 背包容量
     * @return 背包能够装的最大价值
     */
    private int multiPack(List<Integer> weight, List<Integer> value, List<Integer> nums, int bagSize) {
        int[] dp = new int[bagSize + 1];
        dp[0] = 0;
        for (int i = 0; i < weight.size(); i++) {// 物品
            for (int j = bagSize; j >= weight.get(i); j--) {// 背包
                // 增加遍历个数
                // k<=nums.get(i)是因为物品只有nums.get(i)多个
                // j-k*weight.get(i) >= 0 是判断当前的背包能不能放的下k个物品i
                for (int k = 1; k <= nums.get(i) && (j - k * weight.get(i)) >= 0; k++) {
                    dp[j] = Math.max(dp[j], dp[j - k * weight.get(i)] + k * value.get(i));
                }
            }
        }
        return dp[bagSize];
    }

http://www.kler.cn/a/13970.html

相关文章:

  • 购物 · 礼物
  • 【Buildroot】基础知识:目录、根文件系统目录覆盖、编译性能分析(编译时间、目标尺寸、包依赖图)
  • YOLOv7+单目实现三维跟踪(python)
  • Java双亲委派和类加载器
  • springboot+vue小区物业管理系统(源码+文档)
  • XML 简介
  • 数据仓库与数据建模理论
  • Linux系统应用编程(五)Linux网络编程(上篇)
  • 大四的告诫
  • 免费gpt-4-国内使用gpt-4
  • 卷积神经网络(CNN)简单介绍,给出实例并添加详细的注释
  • Java八大基本数据类型
  • CentOS系统安装Intel E810 25G网卡驱动
  • PPOCR -训练模型转推理模型遇到的问题
  • 打造卓越游戏 | 2023 Google 游戏开发者峰会
  • 科大讯飞的2022:夯实“根据地”业务,以技术创新点燃大模型产业落地的“星星之火”...
  • Windows上使用gcc
  • 关系数据库(查询优化)
  • 软件测试工程师需要达到什么水平才能顺利拿到 20k 无压力?
  • ChatGPT实战100例 - (05) ChatGPT 结合 Mermaid 的 Gantt 图表示