Java背包问题动态规划算法分析 动态规划之01背包问题(最易理解的讲解)

createh53周前 (12-18)技术教程17

背包问题
【题目描述】
一个旅行者有一个最多能装 MM 公斤的背包,现在有 nn 件物品,它们的重量分别是W1,W2,…,WnW1,W2,…,Wn,它们的价值分别为C1,C2,…,CnC1,C2,…,Cn,求旅行者能获得最大总价值。

【输入】
第一行:两个整数,MM(背包容量,M<=200M<=200)和NN(物品数量,N<=30N<=30);

第2…N+12…N+1行:每行二个整数Wi,CiWi,Ci,表示每个物品的重量和价值。

【输出】
仅一行,一个数,表示最大总价值。

【输入样例】
10 4
2 1
3 3
4 5
7 9
【输出样例】
12

我们可以通过自己打表的方式找变化求得状态方程
(横向表示容量,j)(纵向表示第几个,i)

1 2 3 4 5 6 7 8 9 10

1 0 1 1 1 1 1 1 1 1 1
2 0 1 3 3 4 4 4 4 4 4
3 0 1 3 5 5 6 8 8 9 9
4 0 1 3 5 5 6 9 9 10 12

dp[i][j]----i表示物品个数,j表示容量,dp[i][j]的值表示在此状态的最大价值
由此我们可以写出状态转移方程:

if(j<w[i])//当容量小于重量,即不拿的情况下
    dp[i][j]=dp[i-1][j]//等于上一次的值
else
     dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);

完整代码如下:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int m, n;
        int[] w = new int[35];
        int[] v = new int[35];
        m = in.nextInt();
        n = in.nextInt();
        int[][] dp = new int[35][205];//m容量,n数目个数

        for (int i = 1; i <= n; i++) {
            w[i] = in.nextInt();
            v[i] = in.nextInt();
        }

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if(j<w[i])
                {
                    dp[i][j]=dp[i-1][j];
                }else
                {
                    dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
                }
            }
        }
        //输出dp数组
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                System.out.print(dp[i][j]+" ");
            }
            System.out.println();
        }
        System.out.println(dp[n][m]);
        in.close();
    }
}

当然,如果容量数字和物品个数很大的时候,这个表会很大,但是dp数组只与自己的上一次有关,会造成空间浪费,所以我们可以改进成滚动数组,减小空间,使其变成一维数组。

小tips:因为是滚动数组,所以如果第二层循环从1开始的话,可能会覆盖上一次的值,所以第二层循环的时候我们从后往前开始!

import java.util.*;
import java.lang.*;

public class Main {
    static int[]dp=new int[205];
    static int[] w = new int[35];
    static int[] v = new int[35];
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int m, n;
        m = in.nextInt();
        n = in.nextInt();
//        int[][] dp = new int[35][205];//m容量,n数目个数


        for (int i = 1; i <= n; i++) {
            w[i] = in.nextInt();
            v[i] = in.nextInt();
        }

        for (int i = 1; i <= n; i++) {
            for (int j = m; j >= 1; j--) {
                if(j>=w[i])
                {
                    dp[j]=Math.max(dp[j],dp[j-w[i]]+v[i]);
                }
            }

        }
        //输出dp数组
//        for (int i = 1; i <= n; i++) {
//            for (int j = 1; j <= m; j++) {
//                System.out.print(dp[i][j]+" ");
//            }
//            System.out.println();
//        }
//        System.out.println(dp[n][m]);
        System.out.println(dp[m]);
        in.close();
    }
}

以上就是java动态规划算法之背包问题的详细内容,谢谢大家支持!

相关文章

Java泛型T、E、K、V、N、?和Object区别和含义

通常我们在看一些源码时,发现全是T、?,晕乎乎的:sob:。于是,把泛型掌握好十分重要!什么是泛型Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机...

干货丨Java 泛型中super T和extends T的区别

代码中经常发现有List< super T>、Set的声明,是什么意思呢?< super T>表示包括T在内的任何T的父类,< extends T>表示包括T在内的...

java高级用法之:JNA类型映射应该注意的问题

简介JNA提供JAVA类型和native类型的映射关系,但是这一种映射关系只是一个大概的映射,我们在实际的应用中还有很多需要注意的事项,本文将会为大家详细讲解在使用类型映射中可能会出现的问题。一起来看...

PHP 8.0正式发布:支持JIT编译器,性能提升高达3倍

美国时间11月26日,PHP团队宣布PHP 8.0正式GA。PHP 8.0是PHP语言的最新主要版本,带来了许多新特性和优化,包括命名参数(named arguments)、联合类型(union ty...

Java开发的5款最佳IDE java开发用什么软件最好

Java是一种广泛使用的编程语言,为开发人员提供了一系列工具和功能,以开发强大且可伸缩的应用程序。然而,为了提高生产力并简化编码过程,开发人员使用集成开发环境(IDE),该环境提供各种功能,以减少开发...

为什么有很多人跑去日本当程序员?

看到这个问题的一瞬间,立马就想到我一学土木的朋友,他现在是在设计院一个月三四千的工资卖命,经常跟我说,他本科同专业的同学毕业自学编程,再加上因为沉迷二次元喜欢日语,日语水平也不错,现在找了个工作被外派...