java背包问题动态规划算法分析

 更新时间:2021年04月08日 15:58:28   作者:灰古  
这篇文章主要介绍了java背包问题动态规划算法分析,想了解算法的同学一定要看一下

背包问题

【题目描述】
一个旅行者有一个最多能装 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动态规划背包的资料请关注脚本之家其它相关文章!

相关文章

  • Java队列同步器之CountDownLatch实现详解

    Java队列同步器之CountDownLatch实现详解

    这篇文章主要介绍了Java队列同步器之CountDownLatch实现详解,CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程执行完后再执行,例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有框架服务之后执行,需要的朋友可以参考下
    2023-12-12
  • Java中文件管理系统FastDFS详解

    Java中文件管理系统FastDFS详解

    这篇文章主要介绍了Java中文件管理系统FastDFS详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • 浅谈抛出异常和捕获异常的一些区别

    浅谈抛出异常和捕获异常的一些区别

    这篇文章主要介绍了抛出异常和捕获异常的一些区别,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 关于注解FeignClient的使用规范

    关于注解FeignClient的使用规范

    这篇文章主要介绍了关于注解FeignClient的使用规范,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • 解析阿里一面CyclicBarrier和CountDownLatch的区别

    解析阿里一面CyclicBarrier和CountDownLatch的区别

    这篇文章主要介绍了阿里一面CyclicBarrier和CountDownLatch的区别是啥,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • 详解Http请求中Content-Type讲解以及在Spring MVC中的应用

    详解Http请求中Content-Type讲解以及在Spring MVC中的应用

    这篇文章主要介绍了Http请求中Content-Type讲解以及在Spring MVC中的应用的相关资料,需要的朋友可以参考下
    2017-02-02
  • Java中常用的设计模式之观察者模式详解

    Java中常用的设计模式之观察者模式详解

    这篇文章主要为大家详细介绍了Java中常用的设计模式之观察者模式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02
  • Java多线程案例之定时器详解

    Java多线程案例之定时器详解

    定时器是一种实际开发中非常常用的组件, 类似于一个 “闹钟”, 达到一个设定的时间之后, 就执行某个指定好的代码。本文主要来和大家聊聊定时器的原理与使用,需要的可以参考一下
    2023-01-01
  • Spring boot 基本部署方式

    Spring boot 基本部署方式

    SpringBoot部署也是非常简单,需要把打包输出的包由jar改为war。具体部署方式大家参考下本文
    2017-08-08
  • linux查找安装jdk并配置JAVA_HOME的方法

    linux查找安装jdk并配置JAVA_HOME的方法

    这篇文章主要介绍了linux查找安装jdk,配置JAVA_HOME,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07

最新评论