背包问题

Backpack II 0-1背包

余生长醉 提交于 2020-02-17 11:09:37
Given n items with size Ai and value Vi, and a backpack with size m . What's the maximum value can you put into the backpack? Given 4 items with size [2, 3, 5, 7] and value [1, 5, 2, 4] , and a backpack with size 10 . The maximum value is 9 . 这是最经典的0-1背包问题。即有n件物品,每个物品有体积Ai, 价值Vi。然后有一个容量为m的背包,要求可以放入背包的最大价值。特点是每件物品只有一件,可以选择放或者不放。 定义状态,背包问题的经典定义,f[i,j]表示前i个物品当中选一些物品组成容量为j的最大价值。转换状态为对于第i 个物体取不取做一个选择。 即f[i,j] = max(f[i-1,j],f[i-1,j-A[i]]+V[i])前者为不取第i 个物体,后者为取第i 个物体。 初始化,注意这题不要求一定装满背包,所以初始化是f[0][j] =0, 如果要求装满,则f[0][0] = 0, f[0][j] = -∞。(来自背包九讲)。 所以这里f[i,j]表示前i个物品当中选一些物品组成容量为j的最大价值,j只是容量,并不是精确的体积.

Backpack III 完全背包

风流意气都作罢 提交于 2020-02-17 11:08:43
Given n kind of items with size A i and value V i ( each item has an infinite number available ) and a backpack with size m . What's the maximum value can you put into the backpack? Given 4 items with size [2, 3, 5, 7] and value [1, 5, 2, 4] , and a backpack with size 10 . The maximum value is 15 . 完全背包问题,即每件物体可取任意件。dp[i,j]表示为前i个物体填满背包可获得的最大价值。DP方程转换为dp[i,j] = max(dp[i-1,j], dp[i, j - Ai] + Vi)。这样转换的复杂度为O(NV),要快于从0-1背包转化过来的从i-1上讨论的转化方程O(NV^2)。 注意这里与0-1背包不一样因为第i件物品可以添加多件.所以DP可以在已加入当前物体的状态下继续添加. 代码入下: class Solution: # @param {int[]} A an integer array # @param {int[]} V an integer array #

LintCode 92.背包问题

我是研究僧i 提交于 2020-02-12 02:33:09
LintCode 92.背包问题 背包问题 对于每个总重量,我们能知道有没有方案能做到,就可以解决。 背包问题中,数组大小和总承重有关 确定状态: 需要知道N个物品是否能拼出重量 W ( W = 0 , 1 , … , M ) W (W =0, 1, …, M) W ( W = 0 , 1 , … , M ) 。 最后一步:最后一个物品(重量 A N − 1 A_{N-1} A N − 1 ​ )是否进入背包 ,**情况一:**如果前 N − 1 N-1 N − 1 个物品能拼出 W W W ,当然前N个物品也能拼出 W W W 。**情况二:**如果前N-1个物品能拼出 W − A N − 1 W- A_{N-1} W − A N − 1 ​ ,再加上最后的物品 A N − 1 A_{N-1} A N − 1 ​ ,拼出 W W W 。 **状态:**设 f[i][w]=能否用前i个物品拼出重量w 转移方程: f[i][w]=f[i-1][w] || f[i-1][w-A[i-1]] 初始条件和边界情况: i个物品可以拼出重量0: f[i][0]=true 0个物品不能拼出大于0的重量: f[0][1...M]=false 边界 : w>A[i-1] 时才能使用 f[i-1][w-A[i-1] public class Solution { /** * @param m: An

动态规划-01背包-Tallest Billboard

白昼怎懂夜的黑 提交于 2020-02-07 19:20:09
2020-02-07 17:46:32 问题描述: 问题求解: 解法一:BF 看问题规模看似可以直接暴力解决。 如果直接去解肯定是会超时的,因为每次将原空间划分成A区域,B区域和剩余区域的时间复杂度为O(3 ^ n)。 但是我们可以将问题进行一下转化,之前有个问题是能否将一个数组中的数划分成两个和相等的子区域那个题目是可以使用dp完成求解的,时间复杂度是O(nsum)。 因此我们可以去构造出所有的挑选可能,并对每个可能产生解的可能去过一遍dp就能完成本题。 但是,本解法并不是最优解。 int ret = 0; int[] nums; List<Integer> res = new ArrayList<>(); public int tallestBillboard(int[] rods) { nums = rods; helper(0, 0); return ret; } private void helper(int start, int sum) { if (start >= nums.length) return; if (sum % 2 == 0 && check(res, sum / 2)) { ret = sum / 2; } helper(start + 1, sum); res.add(nums[start]); sum += nums[start]; if

背包问题:混合背包问题

感情迁移 提交于 2020-02-07 07:03:07
问题描述 有 N 种物品和一个容量是 V 的背包。 物品一共有三类: 第一类物品只能用1次(01背包); 第二类物品可以用无限次(完全背包); 第三类物品最多只能用 si 次(多重背包); 每种体积是 vi,价值是 wi。 求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。 输出最大价值。 输入格式 第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。 接下来有 N 行,每行三个整数 vi,wi,si,用空格隔开,分别表示第 i 种物品的体积、价值和数量。 si=−1 表示第 i 种物品只能用1次; si=0 表示第 i 种物品可以用无限次; si>0 表示第 i 种物品可以使用 si 次; 输出格式 输出一个整数,表示最大价值。 样例 输入样例 4 5 1 2 - 1 2 4 1 3 4 0 4 5 2 输出样例: 8 思路 按照不同的物品分成 01背包 和 完全背包 问题 代码 # include <iostream> # include <cstring> # include <vector> # include <algorithm> using namespace std ; const int N = 1010 ; struct node { int kind ; int v , w ; } ; int n , m ; int f [

背包问题:二维费用背包问题

ぐ巨炮叔叔 提交于 2020-02-06 12:35:46
问题描述 有 N 件物品和一个容量是 V 的背包,背包能承受的最大重量是 M。 每件物品只能用一次。体积是 vi,重量是 mi,价值是 wi。 求解将哪些物品装入背包,可使物品总体积不超过背包容量,总重量不超过背包可承受的最大重量,且价值总和最大。 输出最大价值。 输入格式 第一行两个整数,N,V,M,用空格隔开,分别表示物品件数、背包容积和背包可承受的最大重量。 接下来有 N 行,每行三个整数 vi,mi,wi,用空格隔开,分别表示第 i 件物品的体积、重量和价值。 输出格式 输出一个整数,表示最大价值。 输入样例 4 5 6 1 2 3 2 4 4 3 4 5 4 5 6 输出样例: 8 思路 和01背包问题一样, 这里将01背包问题改成2维 代码 # include <iostream> # include <algorithm> using namespace std ; const int N = 1010 ; int f [ N ] [ N ] ; int n , V , M ; int v , m , w ; int main ( ) { cin >> n >> V >> M ; for ( int i = 1 ; i <= n ; i ++ ) { cin >> v >> m >> w ; for ( int j = V ; j >= v ; j -- ) {

背包问题:0/1背包

假如想象 提交于 2020-02-06 04:20:29
01背包 描述的是一种选,与不选的问题,决策只有两种,故称为 01背包 问题描述 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi,价值是 wi。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。 输入格式 第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。 接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。 输出格式 输出一个整数,表示最大价值。 样例 输入样例 4 5 1 2 2 4 3 4 4 5 输出样例: 8 用f[i, j]代表前 i 个物品容量为 j 时的最大价值 # include <iostream> # include <algorithm> using namespace std ; int f [ 1010 ] [ 1010 ] ; int v [ 1010 ] , w [ 1010 ] ; int n ; int m ; int main ( ) { cin >> n >> m ; for ( int i = 1 ; i <= n ; i ++ ) cin >> v [ i ] >> w [ i ] ; for ( int i = 1 ; i <= n ; i ++ ) for ( int j = 0 ; j <=

AreYouBusy (混合背包)

梦想的初衷 提交于 2020-02-05 23:46:33
题目大意:有 n 组任务,m 个体力,每组任务有 k 个,分类为 f,每个任务花费 x 体力,得到 y 开心值,求最大开心值,若不能完成输出-1      分类为 0:这一组中的 k 个任务至少选择一个。      分类为 1:这一组中的 k 个任务最多选择一个。      分类为 2:这一组中的 k 个任务随便选择。 解法: 对于 0 : 其实就是之前做过的分组背包的变形每组至少选一个 对于 1 : 其实就是分组背包 对于 2 : 其实就是 01背包 .对于分类 0,若当前判断到一个任务 x,则有两种情况: 1)它是该组第一个被选择的任务,则它更新的状态只能是将上一层的状态转移更新到当前位置。 2)它不是第一个被选择的任务,则它可以由当前组的状态转移更新到当前位置。 为了方便判断处理第一个任务,初始化当前层为 -inf 2.对于分类 1,因为只能选一个或者不选,则它只能由上一层状态转移更新 3.对于分类 2,就是普通的 01背包问题 #include <iostream> #include <algorithm> #include <string> #include <string.h> #include <vector> #include <map> #include <stack> #include <set> #include <queue> #include <math

背包问题-多重背包

本小妞迷上赌 提交于 2020-02-05 10:24:57
  有 N种物品和一个容量为 V的背包。第 i种物品最多有 n[i]件可用,每件费用是 c[i],价值是 w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 1 d#include<bits/stdc++.h> 2 using namespace std; 3 4 const int N = ???; 5 int V, m; 6 int dp[N]; 7 int w[N], num[N]; 8 9 void mul(int n,int w){ 10 if(n*w >= V){ 11 for(int i=w; i<=V; i++) 12 dp[i] = max(dp[i], dp[i-w]+w); 13 return ; 14 } 15 int k = 1; 16 int nC = n; 17 while(k < nC){//01背包,做简单的优化 18 for(int i=V; i>=k*w; i--) 19 dp[i] = max(dp[i], dp[i-k*w]+k*w); 20 nC -= k; 21 k *= 2; 22 } 23 for(int i=V; i>=nC*w; i--) 24 dp[i] = max(dp[i], dp[i-nC*w]+nC*w); 25 } 26 int main(){ 27 while(scanf("%d

2020-02-03

狂风中的少年 提交于 2020-02-05 05:25:58
背包问题(贪心法) 【问题描述】设有编号为1、2、…、n的n个物品,它们的重量分别为w1、w2、…、wn,价值分别为v1、v2、…、vn,其中wi、vi(1≤i≤n)均为正数。   有一个背包可以携带的最大重量不超过W。求解目标:在不超过背包负重的前提下,使背包装入的总价值最大(即效益最大化),与0/1背包问题的区别是,这里的每个物品可以取一部分装入背包。 来源: CSDN 作者: 老鱼不老只是愚 链接: https://blog.csdn.net/mili12/article/details/104158522