首页 > 其他分享 >动态规划

动态规划

时间:2023-10-01 16:14:28浏览次数:31  
标签:cnt 背包 int 规划 循环 物品 动态 优化

0-1背包 最多用一次
完全背包 每件物品有无限个
多重背包 每个物品个数不一样 优化
分组背包问题

0-1背包

题目:

0-1背包一维优化
因为,状态转移中只使用了f[i-1]和f[i] ,其他的没用,所以说我们可以使用滚动数组来优化,把f[i][j]改成f[j],不考虑其他的i的存储。
原代码

for(int i = 1;i <= n; i++)
	for(int j = 0; j <= m;j++)
	{
		f[i][j] = f[i-1][j];//保持与上一层i相同,所以直接删掉
		if(j >= v[i]) f[i][j] = max(f[i-1][j], f[i-1][j-v[i]]+w[i]);
	}

优化后

for(int i = 1;i <= n;i++)
	for(int j = m;j >= v[i];j++)
	{
		f[j] = max(f[j],f[j - v[i]]+w[i]);
	}

由于状态改变需要j >= v[i],所以直接令j从v[i]开始循环。但是由于j是递增循环,j-v[i]肯定小于j,所以f[j-v[i]]指的是第i层的值。而原式是f[i-1],所以将第二层循环改成递减。

完全背包问题

完全背包 每件物品有无限个
朴素版
image.png
k为第i个物品的个数,状态转移方程为$f[i,j] = f[i - 1], j - v[i] * k] + w[i] * k$

for(int i = 1;i <= n; i++)
	for(int j = 0; j <= m;j++)
		for(int k = 0;v[i] * k <= j;k++)
			f[i][j] = max(f[i][j], f[i - 1][j - v[i] * k] + w[i] * k);//当k = 0时即i物品不放入的情况

运行时间过长,时间复杂度较大

二维优化

image.png
由图所得,优化后状态转移方程为$f[i, j] = Max(f[i - 1, j], f[i, j - v[i]] + w[i])$

for(int i = 1;i <= n; i++)
	for(int j = 0; j <= m;j++)
	{
		f[i, j] = f[i - 1, j];
		if(j >= v[i]) f[i, j] = Max(f[i, j],f[i, j - v[i]] + w[i]);
	}

一维优化

类似0-1背包问题,将数组变为一维,但完全背包问题不同于0-1背包,状态转移方程中为f[i, j - v[i]]+w[i]

for(int i = 1;i <= n; i++)
	for(int j = v[i]; j <= m;j++)
		f[j] = Max(f[j],f[j - v[i]] + w[i]);

完整推导过程如上

综上,0-1背包问题与完全背包问题的区别,仅仅只在第二层循环,0-1背包中j为从大到小递减循环,完全背包中j为从小到大递增循环。

为什么二者只有这个不同点?我不到啊

多重背包

二进制优化
思路:
将每种物品的s个分割成2的指数相互组合
$1,2,4,8,16……,2^{k} ,c,且2^{k} <s,2^{k+1} >s$,
$1-2^{k}$ 可组合覆盖到$2^{k+1} -1$,有$c<2^{k+1}$ 使得$2^{k+1} -1+c = s$ 实现s的拆分

n种物品,每个s[i]个,全部组合成个数为$\log{s}$的小组合体(新的物品,拥有新的价值和体积),将这些小组合体进行0-1背包求解。

int cnt = 0;
//拆分

for(int i = 1;i <= n;i ++ )
{
	int a, b, s;           //a是物品体积 b是物品价值 s是物品个数
	cin >> a >> b >> s;
	int k = 1;
	while(k <= s)
	{
		cnt ++;
		v[cnt] = a * k;
		w[cnt] = b * k;
		s -= k;
		k *= 2;
	}
	if(s > 0)
	{
		cnt ++;
		v[cnt] = a * s;
		w[cnt] = b * s;
	}
}
n = cnt;
//0-1背包
for(int i = 1;i <= n;i ++)
	for(int j = m;j >= v[i];j --)
		f[j] = max(f[j],f[j-v[i]] + w[i]);


cout<<f[m]<<endl;

标签:cnt,背包,int,规划,循环,物品,动态,优化
From: https://www.cnblogs.com/liyipo/p/17738926.html

相关文章

  • 安防视频监控/视频融合平台EasyCVR海域动态远程视频智能监管
    随着科技的持续进步,智慧海域管理平台已经成为海洋领域监管中的重要工具。与传统的视频监控方式相比,智慧海域管理平台通过建设近岸海域视频监控网、海洋环境监测网和海上目标探测网络等,实现了海洋管理的数字化转型。相较于传统监控方式,智慧海域管理平台实现了自动化和智能化的监管......
  • PPT| IBM采购供应链和财务管理流程数字化规划方案 P172
        IBM咨询在供应链智慧转型上有三点优势,第一点是无边界的供应链,IBM咨询已经实现了从战略到组织文化,以及流程、系统的整条供应链体系的端到端的贯通,能够满足CSCO的任何需求;第二点是IBM原本就拥有技术的DNA,数据驱动供应链离不开技术的支撑。IBM在大数据处理、量子计算等领域......
  • 开源.NetCore通用工具库Xmtool使用连载 - 扩展动态对象篇
    【Github源码】《上一篇》介绍了Xmtool工具库中的图形验证码类库,今天我们继续为大家介绍其中的扩展动态对象类库。<br>扩展动态对象是整个工具库中最重要的一个设计。在软件开发过程中,我们经常需要定义各种各样的数据对象;例如:用于参数传递的数据实体类、用于接口返回结果的Json......
  • 数学建模__动态规划
    动态规划就是,将任务每一步均记录下来,以便将来重复使用时能够直接调用问题描述:给定n个物品,每个物品的重量是Wi,价值是Vi,但是背包最多能装下capacity重量的物品,问我们如何选择才能利益最大化。这里涉及到建模过程,本文章主要讲解代码实现,建模过程较为简略。使用dp[i][j]来表示在容量为......
  • 数学建模__线性规划Python实现
    我使用到的是python库中scipy。'''线性规划'''#目标函数的系数#minz=2x1+3x2-5x3c=np.array([-2,-3,5])#不等式限制条件的系数,转化为小于等于#2x1-5x2+x3<=10,x1+3x2+x3<=12Aup=np.array([[-2,5,-1],[-1,-3,-1]])#必须是二维#右侧系数bup=np.array([-1......
  • 数学建模__非线性规划Python实现
    使用到的是scipy库线性规划指的是目标模型均为线性,除此以外的都是非线性规划,使用scipy提供的方法对该类问题进行求解。fromscipy.optimizeimportminimizeimportnumpyasnp#定义目标函数deffun(args):a,b,c,d=argsv=lambdax:(a+x[0])/(b+x[1])-c*x[0]......
  • openGauss学习笔记-83 openGauss 数据库管理-内存优化表MOT管理-内存表特性-MOT使用内
    openGauss学习笔记-83openGauss数据库管理-内存优化表MOT管理-内存表特性-MOT使用内存和存储规划本节描述了为满足特定应用程序需求,在评估、估计和规划内存和存储容量数量时,需要注意的事项和准则,以及影响所需内存数量的各种数据,例如计划表的数据和索引大小、维持事务管理的内存......
  • 面向对象 静态方法和动态方法 ;静态更先进因为新建和被调用时不需要传self
    展示动态方法 需要加self#A.py调用B的制作伞和扇子fromBimportHandmadeclassWeather:def__init__(self,type):self.type=typedefaction(self):f=Handmade.make_fan(self)u=Handmade.make_umbrella(self)pri......
  • 2023-09-10:用go语言编写。作为项目经理,你规划了一份需求的技能清单 req_skills, 并打算
    2023-09-10:用go语言编写。作为项目经理,你规划了一份需求的技能清单req_skills,并打算从备选人员名单people中选出些人组成一个「必要团队」(编号为i的备选人员people[i]含有一份该备选人员掌握的技能列表)。所谓「必要团队」,就是在这个团队中,对于所需求的技能列表req_skills......
  • 动态规划杂题选练
    \(\text{CF908G}\)题目描述给\(n<=10^{700}\),问1到n中每个数在各数位排序后得到的数的和。答案膜\(1e9+7\)。思路点拨不是很难,自己想一会可以想出来。因为\(n\)比较大,所以我们考虑数位dp。因为每一种数组产生的贡献十分复杂,所以我们将每一数字拆开统计贡献。如果我们认......