Day41题目
卡码46
核心思想:dp[i][j]的含义是:i个物品在j空间下的最大能携带价值,使用一个数组做滚动数组也可以,注意循环的时候空间遍历需要从后向前即可
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
int maxSpace = scanner.nextInt();
int[] value = new int[m];
int[] weight = new int[m];
for(int i = 0 ; i < m ; i ++){
weight[i] = scanner.nextInt();
}
for(int i = 0; i<m ; i ++){
value[i] = scanner.nextInt();
}
testWeightBagProblem(weight,value,maxSpace);
}
/**
* 动态规划获得结果
* @param weight 物品的重量
* @param value 物品的价值
* @param bagSize 背包的容量
*/
public static void testWeightBagProblem(int[] weight, int[] value, int bagSize){
int[][] dp = new int[weight.length][bagSize+1];
for(int j = weight[0]; j <=bagSize ; j ++){
dp[0][j] = value[0];
}
int max = dp[0][bagSize];
for(int i = 1; i < weight.length ; i ++){
for(int j = 0 ; j <= bagSize; j ++){
if(j<weight[i]){
dp[i][j] = dp[i-1][j];
}else{
dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);
}
max = Math.max(dp[i][j],max);
}
}
System.out.println(max);
}
}
LeetCode416分割等和数组
核心思想:包装过的01背包
class Solution {
public boolean canPartition(int[] nums) {
// 数组中的元素拿不拿的01背包问题
// 先计算总和
int sum =0 ;
for(int i = 0; i < nums.length ; i ++){
sum += nums[i];
}
if(sum %2 == 1) return false;
int[][] dp = new int[nums.length][sum/2+1];
// dp[i][j] 表示第i个元素 j表示当前装的元素和的最大值
for(int j = nums[0];j <= sum/2; j ++){
dp[0][j] = nums[0];
}
for(int i = 1 ; i < nums.length ; i ++){
for(int j = 0 ; j <= sum/2 ; j ++){
if(j < nums[i]){
dp[i][j] = dp[i-1][j];
}else{
dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-nums[i]]+nums[i]);
if(dp[i][j] == sum/2){
return true;
}
}
}
}
return false;
}
}