• 动态规划 - 背包问题 & 回文串分割


    目录

    1.背包问题

    1.1 题目描述

    1.2 画图分析

    1.3 思路分析

    1.4 代码示例

    2. 回文串分割

    2.1 题目描述

    2.2 思路分析

    2.3 代码示例


    1.背包问题

    1.1 题目描述

    1. 有 n 个物品和一个大小为 m 的背包. 给定数组 A 表示每个物品的大小
    2. 和数组 V 表示每个物品的价值.问最多能装入背包的总价值是多大?
    3. 1.A[i], V[i], n, m 均为整数
    4. 2.你不能将物品进行切分
    5. 3.你所挑选的要装入背包的物品的总大小不能超过 m
    6. 4.每个物品只能取一次
    7. 5.m <= 1000
    8. len(A),len(V)<=100

    1.2 画图分析

    • 第 i 个商品放入包中的价值

    此时两个等式其实都可以由 F(i, j) = F(i - 1, j - a[i -1]) + v[i -1]  来代替 

    •  第 i 个商品的大小 > 包的大小

    此时 F(i, j) = F(i - 1, j) 

    1.3 思路分析

    状态 F(i, j):从前 i 个商品中选择,包的大小为 j 时的最大价值。(商品的索引从 1 开始,数组的索引从 0 开始)

    状态转移方程:

    • a[i - 1]  >  j             F(i, j) = F(i - 1, j)
    • a[i - 1] <= j             F(i, j) = F(i - 1, j - a[i - 1]) + v[i - 1]

    初始状态F(i, 0) = F(0, j) = 0,由于每一个商品的价值都可能和前一行的某一列有关,为了防止数组越界,我们申请一个行,列比商品数、包都大一的二维数组 array[n + 1][m + 1].

    返回结果array[n][m].

    结合具体示例理解:

     

    1.4 代码示例

    1. public class Solution {
    2. public static int backPackII(int m, int[] a, int[] v) {
    3. int number = a.length;
    4. int[][] array = new int[number + 1][m + 1];
    5. // 初始状态 array[0][j] = array[i][0] = 0
    6. for(int i = 1; i < number + 1; i++) {
    7. for(int j = 1; j < m + 1; j++) {
    8. // 状态转移方程
    9. if(a[i - 1] > j) {
    10. array[i][j] = array[i - 1][j];
    11. } else {
    12. array[i][j] = Math.max(array[i -1][j], array[i - 1][j - a[i - 1]] + v[i - 1]);
    13. }
    14. }
    15. }
    16. // 返回结果
    17. return array[number][m];
    18. }
    19. }

    【优化】一维数组

    上述代码可以优化为只用一个一维数组,循环还是两层,但是要注意的是:内层循环需要从后往前走,因为状态方程需要用未更新之前的值,如果从小到大更新的话,我们是先更新前面这些列的值,那么后面使用的就都是更新过的值了;但是对于二维数组,从前往后,从后往前都是可以的。

    1. public class Solution {
    2. public int backPackII(int m, int[] a, int[] v) {
    3. int number = a.length;
    4. // 省去行
    5. int[] array = new int[m + 1];
    6. for(int i = 1; i < number + 1; i++) {
    7. // 注意从后往前更新
    8. for(int j = m; j > 0; j--) {
    9. if(a[i - 1] <= j) {
    10. // 状态转移方程
    11. array[j] = Math.max(array[j], array[j - a[i - 1]] + v[i - 1]);
    12. }
    13. }
    14. }
    15. return array[m];
    16. }
    17. }

    2. 回文串分割

    2.1 题目描述

    1. 给出一个字符串s,分割s使得分割出的每一个子串都是回文串
    2. 计算将字符串s分割成回文分割结果的最小切割数
    3. 例如:给定字符串s="aab",
    4. 返回1,因为回文分割结果["aa","b"]是切割一次生成的。

    示例1:

    1. 输入:"aab"
    2. 返回值:1

    2.2 思路分析

    问题:s 的最小分割次数

    状态 F(i) :s 的前 i 个字符最小的分割次数

    状态转移方程:

    • [1, i] 是回文串      array[i] = 0;
    • [1, i] 不是回文串,且 i < j && [j + 1, i] 是回文串        min(F(i), F(j) + 1);

    初始状态:F(i) = i - 1i  从 1 开始

    返回结果:F(s.length())

    结合具体实例理解 min(F(i), F(j) + 1)  :

     

    2.3 代码示例

    1. public class Solution {
    2. public boolean isPal(String s) {
    3. int left = 0;
    4. int right = s.length() - 1;
    5. while(left < right) {
    6. if(s.charAt(left) != s.charAt(right)) {
    7. return false;
    8. }
    9. left++;
    10. right--;
    11. }
    12. return true;
    13. }
    14. public int minCut (String s) {
    15. if(s.length() == 0 || s.length() == 1) {
    16. return 0;
    17. }
    18. int[] array = new int[s.length() + 1];
    19. // 初始状态
    20. for(int i = 1; i < array.length; i++) {
    21. array[i] = i - 1;
    22. }
    23. for(int i = 2; i < array.length; i++) {
    24. // 判断整体是否为回文串
    25. if(isPal(s.substring(0,i))) {
    26. array[i] = 0;
    27. } else {
    28. for(int j = 1; j < i; j++) {
    29. // j < i && [j + 1, i] 是否为回文串
    30. if(isPal(s.substring(j, i))) {
    31. // 状态转移方程
    32. array[i] = Math.min(array[i], array[j] + 1);
    33. }
    34. }
    35. }
    36. }
    37. return array[s.length()];
    38. }
    39. }

  • 相关阅读:
    【978.最长湍流子数组】
    glibc: 这个函数是平台定制__syscall_sigreturn;如x86可能就返回 errno=ENOSYS
    AutoCAD Electrical 2022—项目特性
    全功能知识付费源码系统微信小程序+H5+PC端一站通行,自定义你的小程序
    华为OD机试真题 Java 实现【文件目录大小】【2023 B卷 100分】,附详细解题思路
    wy的leetcode刷题记录_Day34
    Object类 --java学习笔记
    THP Maleimide,1314929-99-1,THP-Mal凯新生物双功能螯合剂
    【蓝桥杯选拔赛真题31】python三位数组合个数 青少年组蓝桥杯python 选拔赛STEMA比赛真题解析
    矩阵论—线性子空间、生成子空间、核空间、零度、子空间的交与和、直和
  • 原文地址:https://blog.csdn.net/xaiobit_hl/article/details/126818224