背包问题

有依赖的背包问题(树形dp)

好久不见. 提交于 2019-12-02 10:36:44
有依赖的背包问题 有 N 个物品和一个容量是 V 的背包。 物品之间具有依赖关系,且依赖关系组成一棵树的形状。如果选择一个物品,则必须选择它的父节点。 如下图所示: 如果选择物品5,则必须选择物品1和2。这是因为2是5的父节点,1是2的父节点。 每件物品的编号是 i,体积是 vi,价值是 wi,依赖的父节点编号是 pi。物品的下标范围是 1…N。 求解将哪些物品装入背包,可使物品总体积不超过背包容量,且总价值最大。 输出最大价值。 输入格式 第一行有两个整数 N,V,用空格隔开,分别表示物品个数和背包容量。 接下来有 N 行数据,每行数据表示一个物品。 第 i 行有三个整数 vi,wi,pi,用空格隔开,分别表示物品的体积、价值和依赖的物品编号。 如果 pi=−1,表示根节点。 数据保证所有物品构成一棵树。 输出格式 输出一个整数,表示最大价值。 数据范围 1≤N,V≤100 1≤vi,wi≤100 父节点编号范围: 内部结点:1≤pi≤N; 根节点 pi=−1; 输入样例 5 7 2 3 -1 2 2 1 3 5 1 4 7 2 3 6 2 输出样例: 11 依赖背包问题核心在于将暴力枚举子树的选举情况转换成对体积的枚举 首先枚举每一个子树,然后把子树计算出来,然后将当前树的各个子树作为每一个物品组,这些物品是按照体积来决策的,所以再枚举体积(因为x必须选

背包基础小结

不打扰是莪最后的温柔 提交于 2019-12-02 02:51:39
背包学得太差了要好好复习总结一下 : ) \(01\) /完全 背包 背包问题:有一些物品,每个物品有花费和价值,一般来说求的是在花费不超过给定数的前提下求最大的价值. 一般来说会省略第一维,但是在一些问题转化成的背包问题中不要忘了这一维可能又会被利用起来. //01背包 v表示花费 w表示价值 go(i,1,n) yes(j,t,a[i].v) f[j]=max(f[j],f[j-a[i].v]+a[i].w); //完全背包 go(i,1,n) go(j,a[i].v,t) f[j]=max(f[j],f[j-a[i].v]+a[i].w); 多重背包 每种物品有 \(d_i\) 件. 1.暴力拆分. ​ 将物品拆成 \(\sum d_i\) 件,然后跑 \(01\) 背包. 2.二进制拆分. ​ 将物品拆成 \(\sum log\ d_i\) 件,然后跑 \(01\) 背包. 3.单调队列优化. ​ 我又忘了 \(.jpg\) ,而且发现没有好好讲过单调队列优化多重背包,所以这里详细讲下叭. ​ 发现 \(f_{i,j}\) 一定是从 \(f_{i,j-k\cdot v_i}\) 转移而来, \(f_{i,j+1}\) 一定从 \(f_{i,j+1-k\cdot v_i}\) 转移而来,这两者的候选集合并不重合,也就是说当 \(i\) 确定时,它们两个是不互相影响的. ​

[总结]背包问题

最后都变了- 提交于 2019-12-01 22:06:29
背包问题指这样一类问题,题意往往可以抽象成:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。 就ACM或者其它算法竞赛而言,背包问题可以分为8种类型,其中最基础的是0/1背包问题。作为动态规划的典型问题,其状态转移方程往往需要认真理解并能自行推出。这八种问题分别为:0/1背包问题、完全背包问题、多重背包问题、混合三种背包问题、二维费用背包问题、分组背包问题、有依赖的背包问题、求背包问题的方案总数。 01背包问题 给定 \(n\) 种物品和一个容量为 \(C\) 的背包,物品 \(i\) 的重量是 \(w_i\) ,其价值为 \(v_i\) 。问:应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大? 使用动态规划,阶段就是“物品的件数”,状态就是“背包剩下的容量”,那么很显然 \(f[ i , v ]\) 就设为从前 \(i\) 件物品中选择放入容量为 \(j\) 的背包最大的价值。那么状态转移方程为: \[ f[i][j] = max(f[i-1][j],f[i-1][j-w[i]]+c[i]) \] # 动态规划 时间: O(n*C) 空间:O(n*C) class Solution(): def knapSack(self,w,v,C): n = len(w) dp = [[0 for j in range(C+1

动态规划 初级背包问题。。

流过昼夜 提交于 2019-12-01 09:00:56
状态转移方程 B[n][w]=B[n-1][w-W[i]]+V[i] 表示取走第n个物品,重量为W时的价值量。 W V分别存放重量和价值的数组。#include<iostream> #include<vector> #include<math.h> // 背包问题 using namespace std; int value[]={3,4,5,8,10}; int weight[]={2,3,4,5,9}; const int N=5; const int W=20; int B[N+1][W+1]; int main() { for(int i=1;i<=N;++i) { for(int k=1;k<=W;++k) { if(weight[i-1]>k) { B[i][k]=B[i-1][k]; } else { B[i][k]=max(B[i-1][k],B[i-1][k-weight[i-1]]+value[i-1]); } } } cout<<B[N][W]; return 0; } 来源: https://www.cnblogs.com/yangshengjing/p/11674756.html

背包问题(一):0-1背包问题java(二维数组实现)

匆匆过客 提交于 2019-12-01 07:40:06
用二维数组实现0-1背包就是填写一个二维数组,二维数组的最后一个元素即为背包实现的最大价值。 填写规则是: (1)如果当前背包的重量小于第i个物品的重量时,此时不装第i个物品背包的最大价值即为只考虑前i-1个物品时的最大值。v[i-1][j] (2)如果当时背包的重量大于或等于第i个物品的重量时,此时就要考虑到底要不要装第i个物品。就需要判断一下装上第i个物品是否比不装价值更大。就需要比较val[i-1]+v[i-1][j-weight[i-1]]和v[i-1][j]的大小,取最大值。 示例: 背包最大承重:10 物品重量 weight[]={5,4,6,3} 物品价值 value[]={10,40,30,50} 具体代码如下: import java . util . * ; import java . math . * ; //使用二维数组的方法。 public class Knapsack { public static void Knapsack1 ( int [ ] val , int [ ] weight , int w ) { int n = weight . length ; int [ ] [ ] v = new int [ n + 1 ] [ w + 1 ] ; //二维矩阵 for ( int col = 0 ; col < w ; col ++ ) { /

YTU 2335: 0-1背包问题

僤鯓⒐⒋嵵緔 提交于 2019-11-30 16:39:03
2335: 0-1背包问题 时间限制: 1 Sec 内存限制: 128 MB 提交: 15 解决: 12 题目描述 试设计一个用回溯法搜索子集空间树的函数。该函数的参数包括结点可行性判定函数和上界函数等必要的函数,并将此函数用于解0-1背包问题。 0-1 背包问题描述如下:给定n 种物品和一个背包。物品i 的重量是w i ,其价值为v i ,背包的容量为C。应如何选择装入背包的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品i只有2 种选择,即装入背包或不装入背包。不能将物品i 装入背包多次,也不能只装入部分的物品i。 输入 第一行有2个正整数n和c。n是物品数,c是背包的容量。接下来的1 行中有n个正整数,表示物品的价值。第3 行中有n个正整数,表示物品的重量。 输出 将计算出的装入背包物品的最大价值和最优装入方案输出。第一行输出为:Optimal value is 样例输入 5 10 6 3 5 4 6 2 2 6 5 4 样例输出 Optimal value is 15 1 1 0 0 1 迷失在幽谷中的鸟儿,独自飞翔在这偌大的天地间,却不知自己该飞往何方…… #include<iostream> #include<stdio.h> using namespace std; int ab,c,n,ji[200],h[200]; struct bag

完全背包

江枫思渺然 提交于 2019-11-30 16:03:05
引入 luogu P1616 疯狂的采药 题解: 先看一下这题: acwing3. 完全背包问题 有 N 种物品和一个容量是 V 的背包,每种物品都有无限件可用。 第 i 种物品的体积是 vi,价值是 wi。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。 输入格式 第一行两个整数,N,V,用空格隔开,分别表示物品种数和背包容积。 接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 种物品的体积和价值。 输出格式 输出一个整数,表示最大价值。 数据范围 0<N,V≤1000 0<vi,wi≤1000 输入样例 4 5 1 2 2 4 3 4 4 5 输出样例: 10 分析一下可知,两题很相似,但第二题数据规模小。 (本来就是同一题) 而第二题是一道任何人都看的出来的完全背包问题 ~~(很显然是不是,O(∩_∩)O哈哈~)~~ so,现在的重点就是完全背包问题。 (不了解01背包的请 来这里 ) 此类背包问题中,我们的每种物品有无限多个,可重复选取. 类似于01背包,我们依旧需要考虑前i-1件物品的影响. 此时我们依旧可以设得二维状态 f[i][v] 代表用i件物品填充为体积为v的背包得到的最大价值 依旧很容易写出状态转移方程 f[i][v]=max(f[i−1][v],f[i−1][j−k∗c[i]]+k∗w[i])

[动态规划] 背包问题

不羁岁月 提交于 2019-11-30 15:18:00
问题描述 01背包问题:有n个物品,每个物品有体积和价值两个属性,现在有一个固定容量的背包,要将这些物品放入背包内,使得背包内物品总价值最大,问要如何放? 注意:每个物品的数量为1。 设$V = 14$。 为了描述方便起见,我们用$c_1,c_2,c_3,....c_n$表示物品的体积, 用$w_1,w_2,w_3,....w_n$表示物品的价值,用$V$表示背包的容量,$n$表示物品的数量。 动态规划描述 背包问题是动态规划问题的一种,和分治算法一样,它是将一个大问题分成一个一个的小问题,然后找到大问题和小问题之间的递推式,将一个个小问题组合成大问题, 并且通常要求这些 小问题也要达到最优 。能用动态规划解决的问题一般含有两种性质: 最优子结构 和 重叠子问题。 动态规划从本质上讲就是穷举法, 但是它的却比一般的算法效率要高, 这就是因为它能剪去重叠的子问题,使得总体复杂度不那么高。 解决方法 1.递归方法 我们先从最容易入手的地方开始,用递归的方法来解这个问题。 首先对于每个物品,我们的选择只有两个:放或者不放。我们将所有的可能都穷举出来,就可以得到下面这个树状图(只画了前四个结点): 这个树上每一个分支都只能选一个,每一行就代表一个子问题。我们用$F(i, v_i)$表示前$i$个物品放入背包内的最大价值(即最优方案),此时这个$v_i$指的是放入前$i

递归算法应用

你离开我真会死。 提交于 2019-11-30 14:45:07
一、递归的定义 递归就是程序在运行的过程中调用自己(用自己定义自己) 递归的三要素: 边界条件 递归前进段 递归返回段 递归和栈     递归和栈有这紧密的联系,大多数编译器都是使用栈来实现递归的,当调用方法时,编译器会把这个方法的所有参数和返回地址都压入栈中,然后把控制转移给这个方法。当方法返回时,这些值退栈。参数消失了,并且控制权重新回到返回地址处。     调用一个方法时,所进行的步骤:     1)当一个方法被调用时,它的参数和返回地址压入栈中     2)这个方法可以通过获取栈顶元素访问参数     3)当这个方法返回时,它查看栈已获取返回地址,然后这个地址和所有参数退栈,并且销毁   下图是求阶乘的图示,帮助理解:    二、求整数n的阶乘  1 /** 2 * 求整数n的阶乘 3 * 4 * @param n 整数n 5 * @return 6 */ 7 public static int factorial(int n) { 8 if (n < 0) { 9 return -1;//返回-1证明参数有问题 10 } 11 if (n == 1 || n == 0) { 12 return 1; 13 } else { 14 return n * factorial(n - 1); 15 } 16 } 三、在有序数组中查找目标值(二分法) 1 /** 2 *

c++背包九讲之二维费用背包问题

雨燕双飞 提交于 2019-11-30 03:17:19
一、背包九讲总述 关于动态规划问题,最典型的就是背包九讲,先理解背包九讲后再总结关于动态规划的问题 1、01背包问题 2、完全背包问题 3、多重背包问题 4、混合背包问题 5、二维费用的背包问题 6、分组背包问题 7、背包问题求方案数 8、求背包问题的方案 9、有依赖的背包问题 往前四篇博文已经介绍了前四个问题,有需要的同学可以看一下!! 二、二维费用背包问题 二维费用的背包问题是指:对于每件物品,具有两种不同的费用,选择这件物品必 须同时付出这两种费用。对于每种费用都有一个可付出的最大值(背包容量)。问怎样 选择物品可以得到最大的价值。 故:对于01背包问题、完全背包问题和多重背包问题的方法都完全可以使用,只不过增加一个代价 接下来,01背包问题为例进行解答: 题目描述: 有 N 件物品和一个容量是 V 的背包,背包能承受的最大重量是 M。每件物品 只能用一次 。体积是 v[i],重量是 w[i],价值是 money[i]。 求解将哪些物品装入背包,可使物品总体积不超过背包容量,总重量不超过背包可承受的最大重量,且价值总和最大。输出最大价值。 输入格式 : 第一行3个整数,n,C, W,用空格隔开,分别表示物品件数、背包容积和背包可承受的最大重量。 接下来有 n 行,每行三个整数 v[i],w[i],money[i],用空格隔开,分别表示第 i 件物品的体积、重量和价值。