题目的链接在这里: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]);
}
}