java 牛客网之[动态规划 简单]NC11 【模板】01背包

题目的链接在这里:https://www.nowcoder.com/practice/fd55637d3f24484e96dad9e992d3f62e


题目大意

你有一个背包,最多能容纳的体积是V。

现在有n个物品,第i个物品的体积为v_iv
i

,价值为w_iw
i

(1)求这个背包至多能装多大价值的物品?
(2)若背包恰好装满,求至多能装多大价值的物品?


一、示意图

在这里插入图片描述

二、解题思路

01背包问题

01背包问题

代码如下:

import java.util.*;

public class  Main{
  public static void main(String[] args){
      /**
       * 01背包问题
       * 背包体积是V 有n个物体 第i个物体 的体积是vi 价值是wi 求最大能装多少价值的问题 以及 恰好装满 最大能装多大价值
       * 现在的问题是 需要判断 恰好装满 能装的值
       */
      Scanner sc=new Scanner(System.in);
      int n=sc.nextInt();
      int V=sc.nextInt();
      //这个要放在前面
      int[][]dp=new int[n+1][V+1];
      int[][]dp1=new int[n+1][V+1];
      //对dp1进行初始化 关键就是这个初始化
     
      for(int i=1;i<=V;i++){
          dp1[0][i]=Integer.MIN_VALUE;
      }
      int value[]=new int[n+1];
      int w[]=new int[n+1];
      int l=1;
      int k=n;
      while (k-->0){
          //弄反了
          w[l]=sc.nextInt();
          value[l]=sc.nextInt();
          l++;
      }

      //输出两个答案
      /**
       * dp[i][j]的第一个表示 就是 前i件物品 装满j 最多能放多大价值
       */

/*      //先进行初始化
      for(int i=0;i<=V;i++){
          dp[0][i]=0;
      }*/
      //然后是初始化 第0个物体 全是0吧
   // Arrays.fill(dp[0],0);
      //然后开始遍历 所以还是这个遍历出了问题
     // int max=0;
      for(int i=1;i<=n;i++){
          for(int j=0;j<=V;j++){
              //前i件物品 放入体积是j的最大价值 那就是选择放 第i件物品还是不放
              if(j<w[i]){
                  //那就说明不可能放进第i件物品
                  dp[i][j]=dp[i-1][j];
                  dp1[i][j]=dp1[i-1][j];
              }
              else{
                  //说明这个选择这个第i件物品 j才是状态转移方程
                  dp[i][j]=Math.max(dp[i-1][j-w[i]]+value[i],dp[i-1][j]);
                  dp1[i][j]=Math.max(dp1[i-1][j-w[i]]+value[i],dp1[i-1][j]);
              }
              //这里就进行比大小了
         /*     if(i==n){
                  //说明已经是最后一个了
                  max=Math.max(max,dp[i][j]);
              }*/

          }

      }
      //最后输出的 一个是dp[i]中的最大值 第二个是体积恰好等于v
      System.out.println( dp[n][V]);
      //然后第二个需要判断一下
      dp1[n][V]= (dp1[n][V]>0)?dp1[n][V]:0;
      System.out.println(dp1[n][V]);
      }
  }





在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值