首页 > 其他分享 >DP 复习

DP 复习

时间:2023-10-13 14:48:13浏览次数:52  
标签:费用 件物品 复习 容量 背包 物品 DP 泛化

背包

约定使用 \(v_i\) 表示放入第 \(i\) 件物品的花费,\(w_i\) 表示第 \(i\) 件物品的价值,背包容量 \(M\),物品件数 \(N\)。

01 背包

每种物品仅有一件,可以选择放或不放。

设 \(f(i,j)\) 表示前 \(i\) 件物品恰填满容量为 \(j\) 的背包可以获得的最大价值。则其状态转移方程便是:

\[f(i,j)=\max\{f(i-1,j),f(i-1,j-v_i)+w_i\} \]

若放第 \(i\) 件物品,那么问题就转化为“前 \(i-1\) 件物品放入剩下的容量为 \(j-v_i\) 的背包中”,此时能获得的最大价值就是 \(f(i-1,j-v_i)\) 再加上通过放入第 \(i\) 件物品获得的价值 \(w_i\);
如果不放第 \(i\) 件物品,那么问题就转化为“前 \(i - 1\) 件物品放入容量为 \(j\) 的背包中”,价值为 \(f(i-1,j)\)。

可以用滚动数组优化掉第一维,但注意要逆序枚举容量以达到“每种物品只能取一件”的限制。

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];
	}
}

若要求 恰好装满,则应将 \(f(1\ldots M)\) 初始化为 \(-\infty\),因为如果要求背包恰好装满,那么此时只有容量为 \(0\) 的背包可以在什么也不装且价值为 \(0\) 的情况下被“恰好装满”,反之,如果背包并非必须被装满,那么任何容量的背包都有一个合法解“什么都不装”,这个解的价值为 \(0\),所以初始时状态的值也就全部为 \(0\) 了。

完全背包

与 01 背包相似,但每种物品有无限件。

\[f(i,j) = \max\{f(i-1,j), f(i,j-v_i)+w_i\} \]

可以用滚动数组优化掉第一维,但注意要 顺序 枚举容量以达到“每种物品可以取无限件”的限制。

完全背包的特点是每种物品可选无限件,所以在考虑“加选一件第 \(i\) 种物品”这种策略时,正需要一个可能已选入第 \(i\) 种物品的子结果 \(f(i, j − v_i)\),所以就可以并且必须采用 \(j\) 递增的顺序循环。

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];
	}
}

多重背包

与 01 背包相似,但每种物品最多取 \(k_i\) 件。

二进制拆分每个物品后跑 01 背包即可。

for (int i = 1; i <= n; ++ i)
{
	cin >> a >> b >> m;
 	for (int j = 1; m - j >= 0; j <<= 1)  //二进制拆分优化
	{
		++ cnt;
		v[cnt] = a * j;
		w[cnt] = b * j;  
		m -= j;
	}
 	if (m)
	{
		++ cnt;
		v[cnt] = a * m;
		w[cnt] = b * m;
	}
}

混合背包

有的物品只有一个,有的物品有无限个,还有的物品有有限个。

缝合怪,把前三种代码缝合起来即可。

二维费用背包

对于每件物品,具有两种不同的费用,选择这件物品必须同时付出这两种费用。对于每种费用都有一个可付出的最大值(背包容量)。问怎样选择物品可以得到最大的价值。

设第 \(i\) 件物品所需的两种费用分别为 \(c_i\) 和 \(v_i\)。两种费用可付出的最大值(也即两种背包容量)分别为 \(C\) 和 \(V\)。物品的价值为 \(w_i\)。

费用加了一维,只需状态也加一维即可。设 \(f(i,j,k)\) 表示前 \(i\) 件物品付出两种费用分别为 \(j\) 和 \(k\) 时可获得的最大价值。状态转移方程就是:

\[f(i,j,k) = \max\{f(i-1,j,k), f(i-1,j-c_i,k-v_i)+w_i\} \]

仍然可以滚动数组,按照背包类型确定枚举顺序即可。

有时,“二维费用”的条件是以“最多只能取 U 件物品” 来给出的。这事实上相当于每件物品多了一种“件数”的费用,每个物品的件数费用均为 1,可以付出的最大件数费用为 U。

另一种看待二维背包问题的思路是:将它看待成复整数域上的背包问题。也就是说,背包的容量以及每件物品的费用都是一个复整数。而常见的一维背包问题则是自然数域上的背包问题。所以说,一维背包的种种思想方法,往往可以应用于二位背包问题
的求解中,因为只是数域扩大了而已。

分组背包

有 \(N\) 件物品和一个容量为 \(V\) 的背包。第 \(i\) 件物品的费用是 \(v_i\),价值是 \(w_i\)。这些物品被划分为 \(K\) 组,每组最多选一件物品。

这个问题变成了每组物品有若干种策略:是选择本组的某一件,还是一件都不选。

设 \(f(i,j)\) 表示前 \(f\) 组物品花费费用 \(j\) 能取得的最大权值,则有:

\[f(i,j)=\max\{f(i-1,j),f(i-1,j-v_k)+w_k\} \]

其中 \(k\) 是组 \(i\) 内的一件物品。

for (int i = 1; i <= K; ++ i)
	for (int j = V; j >= 0; -- j)
		for (int k : group[i])
			// 遍历组 i 的每一件物品
			if (j - v[k] >= 0)
				f[j] = max(f[j], f[j - v[k]] + w[k];

有依赖的背包

其实是树形 DP。

咕咕咕。

泛化物品

在背包容量为 \(V\) 的背包问题中,泛化物品是一个定义域为 \(\{x\in\mathbf{Z} \mid 0\leq x\leq V\}\) 的函数 \(h\),当分配给它的费用为 \(v\) 时,能得到的价值就是 \(h(v)\)。

如果给定了两个泛化物品 \(h\) 和 \(l\),要用一定的费用从这两个泛化物品中得到最大的价值,这个问题怎么求呢?事实上,对于一个给定的费用 \(v\),只需枚举将这个费用如何分配给两个泛化物品就可以了。同样的,对于 \([0,V]\) 中的每一个整数 \(v\),可以求得费用\(v\) 分配到 \(h\) 和 \(l\) 中的最大价值 \(f(v)\)。也即

\[f(v) = \max\{h(k) + l(v - k) \mid 0 ≤ k ≤ v\} \]

可以看到,这里的 \(f\) 是一个由泛化物品 \(h\) 和 \(l\) 决定的定义域为 \(\{x\in\mathbf{Z} \mid 0\leq x\leq V\}\) 的函数,也就是说, \(f\) 是一个由泛化物品 \(h\) 和 \(l\) 决定的泛化物品。

本文所有代码均未经过编译。
大部分参考 崔天翼《背包九讲》。

Written with StackEdit.

标签:费用,件物品,复习,容量,背包,物品,DP,泛化
From: https://www.cnblogs.com/Hszzzx/p/dp-review.html

相关文章

  • 数位 dp 学习心得
    感觉非常牛逼。最牛逼的是很多情况下要去掉前导零。去掉前导零的方法通常是先忽略前导零的约束,最后再容斥掉有多少0。LuoguP2602数字计数来自【详细解释】数字计数ZJOJp2602一道练习数位DP的好题-moye到碗里来的博客-洛谷博客(luogu.com.cn)那么我们首先看题,对于这......
  • Almost Sorted (CF F ) (压状dp)
     思路:性质1,相当于重新对这个序列排序性质2, 等式关于值域,对于任意一个都满足,那么就是当前点比前面放入的点的最大值-k都要大,比后面最小值+k都要小,-->每一个点都要满足,那么对于当前点的放置是有限制的,以值域来看1-i里面都已经放置了,那么放置后......
  • 低功耗Sub-1G全频段收发一体芯片DP4306 适用无线对讲机 工业数据采集等应用
    无线电对讲机既是移动通信中的一种专业无线通信工具,又是一种能满足人们生活需要的具有消费类产品特点的消费工具。顾名思义移动通信就是通信一方和另一方在移动中实现通信。它是一种无线的可在移动中使用的一点对多点进行通信的终端设备,可使许多人同时彼此交流,使许多人能同时听到......
  • 云服务测试DPDK
    一、DPDK的系统要求1.1x86上的BIOS的设置先决条件1.1.1 对于大多数平台,不需要特殊的BIOS设置即可使用基本的DPDK功能;1.1.2为了获得额外的HPET定时器和电源管理功能以及小数据包的高性能,可能需要更改BIOS设置;1.2DPDK编译(Ubuntu22.04)......
  • 动态规划——树形DP 学习笔记
    动态规划——树形DP学习笔记引入前置知识:树基础。树形DP,即在树上进行的DP,最常见的状态表示为\(f_{u,\cdots}\),表示以\(u\)为根的子树的某个东东。本文将讲解一些经典题目(树的子树个数、树的最大独立集、树的最小点覆盖、树的最小支配集、树的直径、树的重心、树的中心),以......
  • UOS&windows远程协助:使用xrdp实现远程访问和远程控制
    1.xrdp与vnc的区别在很多场景下,我们需要在局域网内,远程连接到Linux服务器或桌面系统,传统的连接方式主要分为两种。第一种:终端命令行,通过SSH服务实现,没有可视化图形界面,很多人技术牛人喜欢这种方式,因为方便快捷。第二种:图形用户界面,通过xrdp或vnc服务实现,提供可视化图......
  • 换根dp
    看到网上的方法多多少少比较复杂,所以决定写一下。首先对于一道换根dp题应该是先要会不换根版本的。然后可以按照欧拉序(括号序)换根。对于欧拉序中相邻的两个节点必有一条边把它们相连,所以换根的时候只需要从新统计\(1\)个子树的信息。觉得自己的语言表达能力太烂,还是上题目比......
  • 数字预失真(DPD)小试
    前言射频功放的增益响应并非线性的,受到放大管饱和效应的影响,功放不可避免地出现非线性、甚至具有记忆效应的失真。这种非线性失真不仅产生高阶谐波,还会产生互调干扰,降低带内信噪比,影响带外信号。因此,需要一种方式减弱射频功放的非线性增益,数字预失真就是方式之一。ADI有篇文章不......
  • Blazor Server App Cannot find the fallback endpoint specified by route values
    github官方issues中提到的解决方案,CreateBuilder时指定项目绝对路径可以解决。1//指定项目路径,也可以用Assembly.GetCallingAssembly获取2conststringContentRootPath=@"C:\Users\BlazorServer";//项目的路径3conststringApplicationName=nameof(BlazorServer);......
  • 网络基础-OSI七层vsTCP/UDP四层 五层 数据封装
    1.0网络基础1.1网络是什么?网络是信息传输、接收、共享的虚拟平台,通过它把各个点、面、体的信息联系到一起,从而实现这些资源的共享网络分类:局域网,城域网,广域网1.2数据通信方式单播:一对一组播:一对多广播:一对所有2.0OIS七层模型vsTCP/IP四层五层模型 2.1分层思想①......