day30 动态规划03

问题1:0-1背包问题汇总

题目:

https://kamacoder.com/problempage.php?pid=1046

思路:

方法一:泛化为一个二维数组

需要比较的东西也很清晰:归约于抢劫银行这个例子要看几个点?

抢劫银行的例子: 背包 商品价值

由此可以看出递推公式是啥啦

dpij = Math.max(dpi-1j,dpi-1j-capital\[i]+pricei);

方法二:一维数组的方式如何操作?

正序循环,像是把背包装满后又偷偷借用历史值,假装家里永远能多拿一次薯片,其实已经超出家里的存货了!

倒序循环,像是一次性拿家里的存货按最大顺序装进去,保证薯片总数不变,每次只能选自己家里本来的那一包。

dpj : 表示容量为j时的最大价值;

dpj = Math.,max(dpj,dpj-c\[i]+value(i));

代码:

java 复制代码
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int M = sc.nextInt(); // 材料种数
        int N = sc.nextInt(); // 行李容积

        int[] w = new int[M + 1]; // 材料占空间,下标1~M
        int[] v = new int[M + 1]; // 材料价值,下标1~M

        for (int i = 1; i <= M; i++) w[i] = sc.nextInt();
        for (int i = 1; i <= M; i++) v[i] = sc.nextInt();

        // dp[i][j]: 前i种材料,在容量为j时的最大价值
        int[][] dp = new int[M + 1][N + 1];

        // 状态转移
        for (int i = 1; i <= M; i++) {
            for (int j = 0; j <= N; j++) {
                if (j < w[i]) {
                    dp[i][j] = dp[i - 1][j]; // 装不下
                } else {
                    // 选or不选当前材料
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - w[i]] + v[i]);
                }
            }
        }

        System.out.println(dp[M][N]);
    }
}
java 复制代码
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int M = sc.nextInt();
        int N = sc.nextInt();
        int[] w = new int[M + 1];
        int[] v = new int[M + 1];
        for (int i = 1; i <= M; i++) w[i] = sc.nextInt();
        for (int i = 1; i <= M; i++) v[i] = sc.nextInt();

        int[] dp = new int[N + 1];
        
        for (int i = 1; i <= M; i++) {
            // 必须倒序!0-1背包核心
            for (int j = N; j >= w[i]; j--) {
                dp[j] = Math.max(dp[j], dp[j - w[i]] + v[i]);
            }
        }
        System.out.println(dp[N]);
    }
}
问题2 :分割等和子集

题目:

https://leetcode.cn/problems/partition-equal-subset-sum/description/

思路:

step1:dpi 表示容量为i的最大价值

step2:dpj = max(dpj,dpj-nums\[i]+numsi)

step3:dp1 = mums1;

step4:倒叙

step5:打印

!!! 把问题抽象成背包问题 脑子短路啦 !!!

代码:

java 复制代码
class Solution {
    public boolean canPartition(int[] nums) {
        if(nums == null || nums.length == 0) return false;
        int N = 0; // 背包的容量
        for(int i = 0; i < nums.length;i++){
            N += nums[i];
        }
        /*
           step1:dp[i] 表示容量为i的最大价值
           step2:dp[j] = max(dp[j],dp[j-nums[i]]+nums[i])
           step3:dp[1] = mums[1];
           step4:倒叙
           step5:打印
        */
        if(N%2 != 0) return false;
        int dp[] = new int[N/2+1];
        for(int i = 0; i < nums.length;i++){
            for(int j = N/2; j>=nums[i]; j--){
                dp[j] = Math.max(dp[j],dp[j-nums[i]]+nums[i]);
            }
        }
        if(dp[N/2] == N/2){return true;}
        else return false;
    }
}
相关推荐
Jerry3 小时前
LeetCode 101. 对称二叉树
算法
可编程芯片开发4 小时前
基于MPPT最大功率跟踪的离网光伏发电系统Simulink建模与仿真
算法
AI科技星4 小时前
线性算子不是空间映射函数,是全域双螺旋场之间拉伸、旋转、耦合、坍缩的跨空间标准化变换载体《全域数学vs传统数学:人类文明进阶200讲》第80讲
线性代数·算法·矩阵·数据挖掘·回归·乖乖数学·全域数学
米罗篮4 小时前
矩阵快速幂 (Exponentiation By Squaring Applied To Matrices)
c++·线性代数·算法·矩阵
dream_home84074 小时前
图像算法模型NPU适配与算法服务实战指南
人工智能·python·算法·npu 图像服务
大鱼>5 小时前
多宠物家庭智能管理平台:云端架构与多设备协同实战
python·算法·iot·宠物
To_OC6 小时前
LC 22 括号生成:刷完这道题,我终于搞懂回溯剪枝了
javascript·算法·leetcode
To_OC6 小时前
LC 39 组合总和:回溯入门必刷题,我踩过的两个坑都在这了
javascript·算法·leetcode
数字杂技师6 小时前
每条推荐都很准,为什么我还是越刷越无聊?
算法
兰令水6 小时前
hot100【acm版】【2026.7.14打卡-java版本】
java·数据结构·算法·leetcode·面试