【模板】动态规划之背包问题(01背包、多重背包、完全背包) (邮票、Piggy-bank题解)

【算法5.1】背包问题 - 01背包 (至多最大价值、至少最小价值) 01背包 至多至少模板 dp 阅读详情

DP求解核心:状态转移方程和边界条件。

最朴素的01背包问题

注意点:

1. 理解dp[][]的意义,表示前i种物品在重量为j时的最大价值。

2. 在选择放入物品时,注意对背包大小判断。

//二维数组 
#include<iostream>
#include<cstring>
#include<algorithm> 
#define N 1001
using namespace std;
int dp[N][N];	//选择前i物品容量j的价值 
int w[N];	//重量 
int v[N];	//价值 
int main(void){
	int n,m;
	scanf("%d%d",&n,&m);	//n是物品数,m是容量 
	for(int i=1;i<=n;i++){
		scanf("%d",&v[i]);
	}
	for(int i=1;i<=n;i++){
		scanf("%d",&w[i]);
	}
	memset(dp,0,sizeof(dp));
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			if(j>=w[i]){	//如果要放进去,判断是否可以腾出该物品的空间 	
				dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]); 
			}
			else dp[i][j]=dp[i-1][j];
			
		}
	}
	printf("%d\n",dp[n][m]);
	return 0;
} 

01背包问题改进(一维数组)

注意点:

1. 考虑到上述代码种计算dp[i][j]时,实际上只需要dp[i-1][0:j]的元素,因此只用一维数组即可处理。并且注意到只有当j>=v[i](即背包大小大于当前物品的重量)才可能更新。通过这种方式可以减小空间复杂度。

//一维数组 
#include<stdio.h>
#include<cstring> 
#include<algorithm>
#define N 1001
using namespace std;
int dp[N];	//选择前i物品容量j的价值 
int w[N];	//重量 
int v[N];	//价值 
int main(void){
	int n,m;
	scanf("%d%d",&n,&m);	//n是物品数,m是容量 
	for(int i=1;i<=n;i++){
		scanf("%d",&v[i]);
	}
	for(int i=1;i<=n;i++){
		scanf("%d",&w[i]);
	}
	memset(dp,0,sizeof(dp));
	for(int i=0;i<=n;i++){
		for(int j=m;j>=w[i];j--){
			dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
		}
	}
	printf("%d\n",dp[m]);
	return 0;
} 

邮票

题目描述

    有若干张邮票,要求从中选取最少的邮票张数凑成一个给定的总值。     如,有1分,3分,3分,3分,4分五张邮票,要求凑成10分,则使用3张邮票:3分、3分、4分即可。

输入描述

有多组数据,对于每组数据,首先是要求凑成的邮票总值M,M<100。然后是一个数N,N<20,表示有N张邮票。接下来是N个正整数,分别表示这N张邮票的面值,且以升序排列。

输出描述

对于每组数据,能够凑成总值M的最少邮票张数。若无解,输出0。

输入

10
5
1 3 3 3 4

输出

3

#include<iostream>
#include<cstring>
#include<algorithm>
#define INF 1000
using namespace std;
int dp[101][101];//前i张达到j元 需要的张数 
int v[21];//每一张邮票的价格 
int main(void)
{
	int m,n;//凑成m元 有n张 
	while(scanf("%d%d",&m,&n)!=EOF){
		memset(dp,0,sizeof(dp));
		for(int i=1;i<=n;i++)	scanf("%d",&v[i]);
	 	for(int i=0;i<=n;i++) dp[i][0]=0;
		for(int j=1;j<=m;j++) dp[0][j]=INF;//不能从这个状态转移而来 
		dp[0][0]=0;
	 	for(int i=1;i<=n;i++){
	 		for(int j=1;j<=m;j++){
	 			if(j-v[i]>=0){
				 	dp[i][j]=min(dp[i-1][j],dp[i-1][j-v[i]]+1);//要不要第i张? 
				}
				else dp[i][j]=dp[i-1][j];
			 }
		} 
	 	if(dp[n][m]==INF) printf("0\n");
	 	else printf("%d\n",dp[n][m]);
	 	
	}
	return 0;
}

值得学习的链接:https://blog.youkuaiyun.com/wdy_yx/article/details/9495415 

 

完全背包问题

阐述:每种物品可以无限制的重复使用,可以选择放或不放。

Piggy-bank

Description

Before ACM can do anything, a budget must be prepared and the necessary financial support obtained. The main income for this action comes from Irreversibly Bound Money (IBM). The idea behind is simple. Whenever some ACM member has any small money, he takes all the coins and throws them into a piggy-bank. You know that this process is irreversible, the coins cannot be removed without breaking the pig. After a sufficiently long time, there should be enough cash in the piggy-bank to pay everything that needs to be paid. 

But there is a big problem with piggy-banks. It is not possible to determine how much money is inside. So we might break the pig into pieces only to find out that there is not enough money. Clearly, we want to avoid this unpleasant situation. The only possibility is to weigh the piggy-bank and try to guess how many coins are inside. Assume that we are able to determine the weight of the pig exactly and that we know the weights of all coins of a given currency. Then there is some minimum amount of money in the piggy-bank that we can guarantee. Your task is to find out this worst case and determine the minimum amount of cash inside the piggy-bank. We need your help. No more prematurely broken pigs! 

Input

The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing two integers E and F. They indicate the weight of an empty pig and of the pig filled with coins. Both weights are given in grams. No pig will weigh more than 10 kg, that means 1 <= E <= F <= 10000. On the second line of each test case, there is an integer number N (1 <= N <= 500) that gives the number of various coins used in the given currency. Following this are exactly N lines, each specifying one coin type. These lines contain two integers each, Pand W (1 <= P <= 50000, 1 <= W <=10000). P is the value of the coin in monetary units, W is it's weight in grams. 

Output

Print exactly one line of output for each test case. The line must contain the sentence "The minimum amount of money in the piggy-bank is X." where X is the minimum amount of money that can be achieved using coins with the given total weight. If the weight cannot be reached exactly, print a line "This is impossible.". 

Sample Input

3 10 110 2 1 1 30 50 10 110 2 1 1 50 30 1 6 2 10 3 20 4

Sample Output

The minimum amount of money in the piggy-bank is 60. The minimum amount of money in the piggy-bank is 100. This is impossible.

//完全背包 
//Piggy-bank
#include<stdio.h>
#define INF 0x7fffffff
int min(int a,int b){
	return a<b?a:b;
}
struct E{
	int w;
	int v;
}list[501];
int dp[10001];
int main(void){
	int T;
	scanf("%d",&T);
	while(T--){
		int emp,full,n,c;
		scanf("%d%d%d",&emp,&full,&n);
		c = full - emp;
		for(int i=1;i<=n;i++){
			scanf("%d%d",&list[i].v,&list[i].w);
		}
		for(int i=1;i<=c;i++) dp[i]=INF;//限制必须是装满的
		dp[0]=0;
		for(int i=1;i<=n;i++){
			for(int j=list[i].w;j<=c;j++){	//顺序遍历,可以实现从重复选择 
				if(dp[j-list[i].w]!=INF){
					dp[j]=min(dp[j],dp[j-list[i].w]+list[i].v);
				}
			}
		}
		if(dp[c]!=INF) printf("%d\n",dp[c]);
		else printf("Impossible\n");
	}
	return 0;
}

归纳

是否装满背包:除了dp[0][0]以外,dp[0][i]初始化为INF(这里转化为无穷大是因为状态转移方程要求的是较小值),表示不能从这个状态转移而来。

是否可以重复选择(只采用一维数组时):唯一的区别是(01背包)第2个for循环倒序,(多重背包)第2个for循环顺序。

有助于理解的链接:https://blog.youkuaiyun.com/hiudawn/article/details/80138427

多重背包问题

(未完待续)

 

动态规划问题总结

【模板】动态规划之背包问题(01背包、多重背包、完全背包) (邮票、Piggy-bank题解)

【模板】动态规划之最长上升子序列LIS问题、概率DP问题 (烟花题解)

【模板】动态规划之基本思想、最长公共子序列LCS问题 (Coincidence题解)

【模板】动态规划之最大字段和、最大子矩阵问题

LAMMPS+Phonopy计算声子色散曲线 机器学习训练完势函数之后,需要对加以验证。对于晶体而言,色散曲线是其衡量计算是否准确的最重要标准,当然,还有能量,比热,RDF等性质。 阅读详情

相关推荐

自锁电路设计

Hi,uu们,是不是经常要用到自锁电路,通常不是使用555芯片就是用比较器来做自锁,今天我们来简单看下自锁电路的设计.图1采用了比较器构建了一个自锁电路,采用低电平复位,当需要复位的时候志需要将反向端的二极管拉低一下即可,免去 三极管控制同相端和电源短接的麻烦。图1:比较器构建的自锁电路也可以使用555去构建,如下图2所示.图2:使用555构建的自锁电路工作原理见555的真值表,真值表如表1所示.表1:555电路真值表相对来说555还是比较贵,所以我就想能不能有个便宜的方法做个自锁电路,构建电路如下图3所示

weixin_43884675的博客 7061

【dp】背包问题

背包问题是⼀种组合优化的问题。问题可以描述为:给定⼀组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。01背包问题:每个物品只有⼀个完全背包问题:每个物品有无限多个多重背包问题:每件物品最多有 x 个混合背包问题:每个物品会有上面三种情况分组背包问题:物品有 n 组,每组物品里有若干个,每组里最多选⼀个物品不一定装满背包背包一定装满限定条件只有⼀个:比如体积 -> 普通的背包问题限定条件有两个:比如体积 + 重量 -> 二维费用背包问题。

YoungMLet的博客 2203

如何在STM32上5分钟搞定nanopb协议传输?附完整代码示例

本文提供了在STM32微控制器上快速集成nanopb协议传输的实战指南。通过详细的步骤,从.proto文件定义、代码生成到STM32CubeIDE项目移植,帮助开发者利用nanopb这一轻量级Protocol Buffers C语言实现,在5分钟内构建高效、跨平台的嵌入式设备通信框架,并附有完整的代码示例。

jwt8token的博客 838

背包九讲(dp问题详解)

【代码】背包九讲(dp问题详解)

weixin_64394633的博客 2191

基于fMRI数据计算脑脊液(CSF)与全脑BOLD信号的时间耦合分析

BOLD和CSF信号有多相似CSF信号要延迟多少时间才能最匹配BOLD信号BOLD-CSF的互相关公式lag:时间延迟采样点数BOLD信号CSF信号延迟时间点对应的相关系数。

Rose9614的博客 2980

深入解析luckyExcel处理xlsx与xls文件的实战技巧

本文深入解析了使用luckyExcel库在前端处理.xlsx与.xls文件的实战技巧。针对.xlsx文件,可直接调用API转换;对于老旧的.xls格式,则需结合SheetJS进行预处理。文章详细介绍了核心API的使用、两种格式的处理流程、数据提取方法以及性能优化建议,为开发在线Excel编辑应用提供了完整解决方案。

cherry的博客 817

DP:01背包问题

背包问题是⼀种组合优化的NP完全问题。 本质上是为了找出“带有限制条件的组合最优解”

weixin_51142926的博客 4298

13、数据可视化与分组操作:Danfo.js 实战指南

本文深入介绍了如何使用 Danfo.js 进行数据可视化与分组操作。内容涵盖多种图表的创建与配置,如折线图、散点图、箱线图、小提琴图、直方图和柱状图,并结合 Plotly.js 实现丰富的交互式可视化效果。同时,详细讲解了数据聚合的‘分割-应用-组合’模式,包括分组数据、遍历分组、apply 方法及 agg 聚合操作,帮助开发者高效处理和分析结构化数据。适用于 Dnotebook、HTML 及主流前端框架的应用场景。

o1p2q3r的博客 98

背包问题(DP)

​ 背包问题指这样一类问题,题意往往可以抽象成:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。

qq_71356343的博客 347

Python 实战:全面解析“微信搜一搜”内容爬取,从入门到企业级架构

本文将带你从零搭建爬虫项目,采用 Requests、Scrapy、Selenium、Proxy 池、中间人监控(如 Fiddler/mitmproxy)、分布式调度、数据库持久化、断点续抓等方案,实现可持续、抗封能力强的内容抓取系统。理解“微信搜一搜”页面结构与 Javascript 渲染逻辑;使用 Scrapy 框架搭建分布式爬虫;使用 Selenium 模拟浏览器抓取;构建代理池提升爬取成功率;对抗验证码、IP 封禁与 cookie 过期问题;

2201_76125261的博客 1392

Sigrity System SI SerialLink模式进行SFP+协议仿真分析-PCB操作指导

Random(Rj):随机抖动,该抖动用高斯概率分布来描述,通常是由热噪声和其它随机噪声引起的,默认为1%UI RMS(平均值),即和标准值的偏差为1%UI。Random(Rj):随机抖动,该抖动用高斯概率分布来描述,通常是由热噪声和其它随机噪声引起的,默认为1%UI RMS(平均值),即和标准值的偏差为1%UI。Random(Rj):随机噪声,是由信号电压的随机波动引起的,默认为1mv RMS(平均值),即和标准值的偏差为1mv。

weixin_54787054的博客 501

多种类型的背包问题

一、背包问题 1、0/1背包:将物品划分为两个集合:①从1~i中选不包含i且体积小于等于V的,即f(i-1,j) ②从1~i中选包含i且体积小于等于V的,即f(i-1,j-v[i])+w[i];f(i,j)表示从1~i中选且体积不超过j的物品的最大价值。 #include<iostream> using namespace std; const int N=1e5+10; const int M=1e3; int v[N],w[N],dp[N][M]; int main() { int

weixin_52694528的博客 726

基于注意力机制的行人重识别(Reld)模型论文解读----Relation-Aware Global Attention for Person Re-identification

任务概述:在多摄像头的复杂场景中,快速定位查找指定目标的所有结果。

qq_52053775的博客 1894

动态规划(DP)---- 01背包入门详解----二维图是学会的关键

如果咱们假设i为枚举到第i个物品,dp[i]代表当前的最大金额,在这里咱们要想给其加入限制条件,是不是可以开辟一个二维数组,因为二维数组内两个参数可以代表两个含义,所以设置dp[][],其中举个例子dp[i][j - w[i]]中i代表枚举到第几个物品,j - w[i]代表因为背包加入第i个物品导致背包空间剩下j - w[i]。1.咱们分析如何定义dp数组的含义,在这里需要咱们细心阅读题干,题干表明背包容量是固定的,如果超过背包容量是不就代表无法拿这个物品,所以背包容量是其。非线性DP类似树形图,可以。

记得开心一点嘛的博客 1775

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

【算法笔记】三种背包问题——背包 DP

背包(Knapsack)问题是经典的动态规划问题,也很有实际价值。这是最原始的01背包问题(即每个物品只能选000或111次)。下面我们来看如何求解。 令fi,jf_{i,j}fi,j​表示只考虑前iii个物品的情况下,容量为jjj的背包所能装的最大总价值。则最终答案为fn,Wf_{n,W}fn,W​,状态转移方程为:...

天生我材必有用,千金散尽还复来。 7892

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

算法套路十四——动态规划之背包问题:01背包、完全背包及各种变形

0-1背包:有n个物品,第i个物品的体积为w[i],价值为v[i],每个物品至多选一个, 求体积和不超过capacity时的最大价值和,其中i从0开始。

Pistachiout的学习博客 3144

背包问题_(DP经典),一,(01背包,填满背包)

背包系列已更新。

WQhuanm的博客 521

蓝桥杯备赛 week 4 —— DP 背包问题

蓝桥杯备赛 week 1 —— DP 背包问题。这篇文章主要是准备蓝桥杯竞赛同学所写,为你更好准备蓝桥杯比赛涉及的算法知识点。不知道你是否苦恼于不知算法从何学起,苦恼于网上资料稀少,或者复杂难懂,这篇文章就是帮助这部分同学的。

jupangMZ的博客 1561

DP问题之01背包如此简单

看完这篇文章,学会人生中第一个背包问题

qq_52416556的博客 4688

dp-背包问题

dp问题

weixin_48155735的博客 274

三十八、动态规划——背包问题( 01 背包 + 完全背包 + 多重背包 + 分组背包 + 优化)

背包问题( 01 背包 + 完全背包 + 多重背包 + 分组背包 + 优化)

靡不有初 鲜克有终 5241

算法学习之动态规划DP——背包问题

一维状态第i轮对体积为 3的物品进行决策,则f[7]由f[4]更新而来,这里的f[4]正确应该f[i-1][4],但从小到大枚举j这里的f[4]在第i轮计算却变成了f[i][4]。当逆序枚举背包容量j时,我们求f[7]同样由f[4]更新,但由于是逆序,这里的f[4]还没有在第i轮计算,所以此时实际计算的f[4]仍然是f[i - 1][4]。在二维情况下,状态f[i][j]是由上一轮i - 1的状态得来的,f[i][j]与f[i - 1][j]是独立的。这Si个数分别为2^0, 2^1, 2^2……

m0_72955669的博客 5924

【蓝桥杯准备打卡-基础算法笔记DP篇】-1.【01背包】

01背包问题

m0_55653575的博客 501

DP 01背包问题

一、01背包问题 例题 首先分析这个题目,用y总的背包问题分析图解

weixin_61438881的博客 1034

背包问题大全(动态规划)

背包问题是动态规划非常重要的一类问题,它有很多变种,但题目万变不离其宗。我们需要抓住关键的解题思路。

weixin_45746505的博客 6万+

01背包问题DP详解

不拿时 f[i - 1][j] 与 拿时 f[i - 1][j - v[i]] + w[i] (因为要拿第i个物品,所以先把第i个物品去除掉,找出去除第i个物品所生背包容量的前i - 1个物品选出的最大值)的最大值即可。而我们要的是上一层f[i-1][j-v[i]]+w[i]的值,所以如果从大到小遍历,那么本层更小的j - v[i]在本层还没被遍历过。第一行两个整数,N,V,用空格隔开,分别表示物品数量和背包容积。

m0_62233297的博客 599

背包问题DP(01背包 完全背包 多重背包 分组背包)

{背包问题的简介 背包问题的定义 背包问题的分类} 01背包问题{二维数组代码实现 一维数组优化实现 扩展:记忆化搜索 + DPS 实现 01背包之恰好装满} 完全背包问题(二维数组代码实现 一维数组优化实现) 多重背包问题【朴素解法(二维数组代码实现 一维数组优化实现)二进制解法(二维数组代码实现 一维数组优化实现)】 分组背包问题(二维数组代码实现 一维数组优化实现)

咸鱼势力登场 1198
上一篇: 【机试】子串计算 (STL)
下一篇: 【模板】动态规划之基本思想、最长公共子序列LCS问题 (Coincidence题解)
coderwait
博客等级 码龄9年 20粉丝 210原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值