代码随想录——第三十五天

正式开始背包问题,背包问题还是挺难的,虽然大家可能看了很多背包问题模板代码,感觉挺简单,但基本理解的都不够深入。

如果是直接从来没听过背包问题,可以先看文字讲解慢慢了解 这是干什么的。

如果做过背包类问题,可以先看视频,很多内容,是自己平时没有考虑到位的。

背包问题,力扣上没有原题,大家先了解理论,今天就安排一道具体题目。

详细布置

01背包问题 二维

https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-1.html 

视频讲解:https://www.bilibili.com/video/BV1cg411g7Y6 

import java.util.Scanner;

class Solution{

    public static void main(String[] args){

        Scanner sc = new Scanner(System.in);

        int m = sc.nextInt();//材料种类

        int n = sc.nextInt();//行李空间

        int[] weight = new int[m];

        int[] value = new int[m];

        for(int i = 0; i < m; i ++){

            weight[i] = sc.nextInt();

        }

        for(int i = 0; i < m; i ++){

            value[i] = sc.nextInt();

        }

        //定义dp数组

        int[][] dp = new int[m][n+1];//行坐标是物品编号 有m个物品 0-m-1 纵坐标是行李空间 0-n

        //初始化dp数组

        int max = -1;

        for(int j = weight[0]; j <= n; j ++){// 初始化第一行

            dp[0][j] = value[0];

            if(dp[0][j] > max) max = dp[0][j];

        }

        // 遍历和递推

        for(int i = 1; i < m; i ++){

            for(int j = 1; j <= n; j ++){

                if(j < weight[i]) dp[i][j] = dp[i-1][j];

                else dp[i][j] = Math.max(dp[i-1][j], value[i] + dp[i-1][j-weight[i]]);

                if(dp[i][j] > max) max = dp[i][j];

            }

        }

   System.out.println(max);

    }

}

class Main

Error: Could not find or load main class Main

:     non-zero return = 1

// 逻辑对了


01背包问题 一维

https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-2.html 

视频讲解:https://www.bilibili.com/video/BV1BU4y177kY 

import java.util.Scanner;

class Main{

    public static void main(String[] args){

        Scanner sc = new Scanner(System.in);

        int m = sc.nextInt();//材料种类

        int n = sc.nextInt();//行李空间


        int[] weight = new int[m];

        int[] value = new int[m];


        for(int i = 0; i < m; i ++){

            weight[i] = sc.nextInt();

        }


        for(int i = 0; i < m; i ++){

            value[i] = sc.nextInt();

        }


        //定义dp数组


        int[] dp = new int[n+1];//行坐标是物品编号 有m个物品 0-m-1 纵坐标是行李空间 0-n


        //初始化dp数组

        dp[0] = 0;


        // 遍历和递推

        for(int i = 0; i < m; i ++){

            for(int j = n; j >= weight[i]; j --){

                dp[j] = Math.max(dp[j], value[i] + dp[j-weight[i]]);

            }

        }

        System.out.println(dp[n]);

    }

}

不用max 

416. 分割等和子集

本题是 01背包的应用类题目

https://programmercarl.com/0416.%E5%88%86%E5%89%B2%E7%AD%89%E5%92%8C%E5%AD%90%E9%9B%86.html   

视频讲解:https://www.bilibili.com/video/BV1rt4y1N7jE

class Solution {

    public boolean canPartition(int[] nums) {

        int sum = 0;

        for(int i : nums) sum += i;

        if(sum %2 != 0) return false;

        // 容量

        int n = sum / 2;

        //数量

        int m = nums.length;

        //cost数组和value数组 nums

        // dp数组

        int[] dp = new int[n+1];

        // 初始化

        dp[0] = 0;

        //遍历

        for(int i = 1; i < m; i ++){

            for(int j = n; j >= nums[i]; j --){

                dp[j] = Math.max(dp[j], nums[i] + dp[j - nums[i]]); 已经在j这一行变化了

            }

        }

        if(dp[n] == n) return true;//拼写

        return false;

    }

}

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容