背包问题
1.在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i]
样例
样例 1:
输入: [3,4,8,5], backpack size=10
输出: 9
样例 2:
输入: [2,3,5,7], backpack size=12
输出: 12
public class Solution {
/**
* @param m: An integer m denotes the size of a backpack
* @param A: Given n items with size A[i]
* @return: The maximum size
*/
public int backPack(int m, int[] A) {
// write your code here
//f[i][w]=f[i-1][w] or f[i-1][w-ai]
int n = A.length;
//n件物品,背包大小为 m
boolean[][]dp = new boolean[n+1][m+1];
dp[0][0]=true;
for(int i=1;i<=n;++i) {
for(int j=0;j<=m;++j) {
dp[i][j] = dp[i-1][j];
//容量为j
if(j>=A[i-1]) {
dp[i][j] = dp[i][j]||dp[i-1][j-A[i-1]];
}
}
}
for(int i=m;i>=0;--i) {
if(dp[n][i])
{
return i;
}
}
return 0;
}
}
//dp方程
dp[i][w]=dp[i-1][w] || dp[i-1][w- A[i]]
设 dp[i][w] 表示能否用前 i 个物品拼出重量为 w(true or false)
初始条件:
1.0个物品可以拼出重量为0
2. 0 个物品不能拼出 大于0 的重量
563. 背包问题 V
中文English
给出 n 个物品, 以及一个数组, nums[i] 代表第i个物品的大小, 保证大小均为正数, 正整数 target 表示背包的大小, 找到能填满背包的方案数。
每一个物品只能使用一次
样例
给出候选物品集合 [1,2,3,3,7] 以及 target 7
结果的集合为:
[7]
[1,3,3]
返回 2
public class Solution {
public int backPackV(int[] nums, int target) {
//dp[i][w]=dp[i-1][w]+dp[i-1][w- nums[i-1]]
int n = nums.length;
int[][]dp = new int[n+1][target+1];
dp[0][0]=1;
for(int i=1;i<=n;++i)
{
//i个物品,j容量
for(int j=0;j<=target;++j) {
dp[i][j] = dp[i-1][j];
if(i>=1&&j>=nums[i-1]) {
dp[i][j] +=dp[i-1][j-nums[i-1]];
}
}
}
return dp[n][target];
}
}
564. 组合总和 IV
中文English
给出一个都是正整数的数组 nums,其中没有重复的数。从中找出所有的和为 target 的组合个数。
样例
样例1
输入: nums = [1, 2, 4] 和 target = 4
输出: 6
解释:
可能的所有组合有:
[1, 1, 1, 1]
[1, 1, 2]
[1, 2, 1]
[2, 1, 1]
[2, 2]
[4]
样例2
输入: nums = [1, 2] 和 target = 4
输出: 5
解释:
可能的所有组合有:
[1, 1, 1, 1]
[1, 1, 2]
[1, 2, 1]
[2, 1, 1]
[2, 2]
注意事项
一个数可以在组合中出现多次。
数的顺序不同则会被认为是不同的组合
public class Solution {
/**
* @param nums: an integer array and all positive numbers, no duplicates
* @param target: An integer
* @return: An integer
*/
public int backPackVI(int[] nums, int target) {
// dp[i] = sum (dp[i...])
int[]dp = new int[target+1];
dp[0]=1;
for(int i=1;i<=target;++i) {
//dp[i] = dp[i];
for(int num:nums) {
if(i>=num) {
dp[i]+=dp[i-num];
}
}
}
return dp[target];
}
}
题目链接:
01背包
[编程题]01背包
热度指数:1979时间限制:C/C++ 1秒,其他语言2秒空间限制:C/C++ 128M,其他语言256M
现有一个容量大小为V的背包和N件物品,每件物品有两个属性,体积和价值,请问这个背包最多能装价值为多少的物品?
输入描述:
第一行两个整数V和n。
接下来n行,每行两个整数体积和价值。1≤N≤1000,1≤V≤20000。
每件物品的体积和价值范围在[1,500]。
输出描述:
输出背包最多能装的物品价值。
示例1
输入
6 3
3 5
2 4
4 2
输出
9
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int v = sc.nextInt(); //背包容量
int n = sc.nextInt();//n件物品
//体积和 价值
int[][]p = new int[n][2];
for(int i=0;i<n;++i) {
p[i][0]=sc.nextInt();
p[i][1]=sc.nextInt();
}
//dp[i][j]:设为 i件物品,j容量,dp[i][j]为最大价值
int[][]dp = new int[n+1][v+1];
for(int i=1;i<=n;++i) {
for(int j=1;j<=v;++j) {
if(j<p[i-1][0]) {
dp[i][j]=dp[i-1][j];//装不下
}else{
dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-p[i-1][0]]+p[i-1][1]);
}
}
}
System.out.println(dp[n][v]);
}
}