首页 > 其他分享 >背包 dp 一些小 trick 的记录

背包 dp 一些小 trick 的记录

时间:2024-12-11 19:57:55浏览次数:7  
标签:背包 优解 times trick 物品 最优 dp

前言

学习背包 dp,遇到了一些觉得有典型性的一些题目,故记录在此,方便以后查看。

如果以后发现有价值的会更新。

P1417 烹调方案

01 背包。

特殊点:物品的价值在动态变化,物品 \(1\) 在物品 \(2\) 前先做不一定更优,即无后效性。

但由于价值的变化满足式子 \(a_i - t \times b_i\),那么对于任意的 \(\forall t\in [1,T]\),物品 \(i\) 想要比物品 \(j\) 先做,应当满足:

\[a_i-t\times b_i+a_j-(t+c_i)\times b_j > a_j-t\times b_j+a_i-(t+c_j)\times b_i \]

化简可得:

\[\dfrac{c_i}{b_i} < \dfrac{c_j}{b_j} \]

因此按以上式子对物品排序再进行 dp 即可。

P6771 太空电梯

多重背包,观察数据范围可知不需要使用单调队列或二进制拆分优化。

特殊点:物品有着自己独有的一个体积,如果不考虑顺序直接 dp,会导致出现不同方案尽管选择的方块一样但是由于高度限制导致有些合法有些不合法。

因此一个显然的贪心是将物品按照 \(a_i\) 排序再进行 dp。

P2979 [USACO10JAN] Cheese Towers S

完全背包。

特殊点:部分物体放在最后时可以减少以前物品的体积。很显然,由于减少的体积不可叠加,因此我们没必要为了减少体积放多个大奶酪。

由于选择压在上方的大奶酪是完全独立于整个过程的,因此我们可以先不考虑大奶酪计算 \([0,1.25\times T]\) 的最优解,再枚举大奶酪计算在上面压一块大奶酪的最优解。

P1858 多人背包

01 背包求前 \(k\) 优解。(\(k \le 50\))

方案:由于 \(k\) 比较小,我们可以直接加一个维度,表示当前阶段当前状态下的第 \(k\) 优解。

那么状态转移方程可以写为:(为方便理解未进行降维优化)

\[f_{i,j,k}\gets \max(f_{i-1,j,x},f_{i-1,j-w_i,y}+v_i) \]

其中的 \(x,y\) 表示曾经阶段曾经状态的第 \(x,y\) 优解,如果我们暴力枚举肯定超时,但是很显然的是:

  • 最优解肯定由 \(f_{i-1,j}\) 的最优解和 \(f_{i-1,j-w_i}+v_i\) 的最优解推出。
  • 如果最优解由 \(f_{i-1,j}\) 的最优解推出,那么次优解由 \(f_{i-1,j}\) 的次优解和 \(f_{i-1,j-w_i}+v_i\) 的最优解推出;
  • 如果最优解由 \(f_{i-1,j-w_i}+v_i\) 的最优解推出,那么次优解由 \(f_{i-1,j}\) 的最优解和 \(f_{i-1,j-w_i}+v_i\) 的次优解推出。
  • 所以 \(f_{i-1,j}\) 的 \(k\) 优解如果由 \(f_{i-1,j}\) 的 \(x\) 优解推出,则 \(k+1\) 优解由 \(f_{i-1,j}\) 的 \(x+1\) 优解和 \(f_{i-1,j-w_i}+v_i\) 的 \(y\) 优解推出;反之亦然。

因此我们便可以书写以下代码(进行降维优化):

for (int i = 1; i <= n; i++) {
	for (int j = V; j >= w[i]; j--) {
		for (int t = 1,x = 1,y = 1; t <= k; t++) {
			int t1 = f[j][x],t2 = f[j-w[i]][y]+v[i];
			if (t1 <= t2) {
				tmp[t] = f[j-w[i]][y++]+v[i];
			}else{
				tmp[t] = f[j][x++];
			}
		}
		for (int t = 1; t <= k; t++) {
			f[j][t] = tmp[t];
		}
	}
}

注意由于 \(f\) 数组的任意优解必须要由上一阶段的推出,因此本阶段的值应当先由临时数组存好,防止本阶段使用本阶段代码导致错误。

标签:背包,优解,times,trick,物品,最优,dp
From: https://www.cnblogs.com/bbbbeta/p/18600571

相关文章

  • CDP与Selenium相结合——玩转网页端自动化数据采集/爬取程序
    SeleniumSelenium是一款开源且可移植的自动化软件测试工具,专门用于测试网页端应用程序或者采集网页端数据。它能够在不同的浏览器和操作系统上运行,具有很强的跨平台能力。Selenium可以帮助测试人员更高效地自动化测试基于Web网页端的应用程序,也可以帮忙开发者方便地完成网页端数......
  • 强化学习(人工智能) —— DDPG、TD3、SAC、SQL算法是不是Actor-Critic算法?
    强化学习算法是人工智能领域发展最为强劲的一个分支,但是很多人都将注意力放在了算法模型的发展上而忽略了其基本理论上的一些概念,本文就讨论一下强化学习算法的一些基本概念的界定上。来源:https://ai.stackexchange.com/questions/39545/why-is-soft-q-learning-not-an-acto......
  • RS232转PROFIBUS DP转换器怎么接线
    大家好,今天我们要来讨论的是一个非常广泛的应用,这个应用可以让我们的现场设备与PROFIBUS-DP主站实现无缝连接。那么,这个神奇的产品就是捷米特JM-RS232-DP型RS232转PROFIBUS-DP协议转换器。 那么,你可能会有这样的疑问,这个转换器到底能做什么呢?它又有什么优势呢?别着急,接下来,我们......
  • SIP和SDP协议中的SESSION ID
    众所周知,SDP协议中Origin("o=")字段名提供会话发起者的信息,其中有会话ID(sessionid)的属性。在VOLTE呼叫场景中,稍加留意,会发现SIPInvite消息的Header中也出现了一个类似的SESSION-ID的属性。 下面简单介绍一下这两个会话ID的区别。SDP协议中的会话ID:详细内容参见RFC456......
  • url_for函数、视图函数、endpoint参数
    在Flask中,url_for函数、路由装饰器中的endpoint参数以及视图函数名称之间的关系是理解FlaskURL路由机制的关键。先看示例代码:HTML文件代码:<li><ahref="{{url_for('val1',title='index首页')}}">首页1</a></li>python文件代码:@app.route('/',endpoin......
  • 记录一个很简单的压缩编码--ADPCM
    此篇文章在2022年9月22日被记录ADPCM是一种很简单实现的音频编码方式,真正的PCM相当占用内存,这对网络和内存的压力是相当大的,因此通常需要压缩编码,ADPCM是一种可以运行在单片机上的编码方式,原理如下:由于声音信号具有波形上的连续性,因此相邻两个采样值大小也非常接近,记录单个采......
  • 百问FB网络编程 - UDP编程简单示例
    6.5UDP编程简单示例​UDP服务器首先进行初始化操作:调用函数socket创建一个数据报类型的套接字,函数bind将这个套接字与服务器的公认地址绑定在一起。然后调用函数recvfrom接收UDP客户机的数据报。UDP客户机首先调用函数socket创建一个数据报套接字,然后调用函数sendto向服......
  • 什么是“Error establishing a database connection”错误,为什么会出现在WordPress中?
     “Errorestablishingadatabaseconnection”错误是WordPress中常见的数据库连接错误,表示WordPress无法成功连接到数据库。这种错误可能会导致网站无法正常显示内容,甚至完全无法访问。以下是可能导致该错误的一些常见原因:数据库登录凭证错误或已更改:如果wp-config.php文......
  • 如何排查WordPress数据库错误?
    排查WordPress数据库错误需要系统地检查各个可能的故障点。以下是一些常用的排查方法,帮助您快速定位并解决问题:检查WordPress版本和插件更新:确保您的WordPress版本和插件是最新的。过时的版本可能会导致兼容性问题,从而引发数据库错误。解决方法:登录到WordPress后台,导航到“......
  • 解题报告-论对“分组背包”的新理解
    解题报告-论对“分组背包”的新理解分组背包都知道,但是有一种新式分组背包,它不像我们想的那样每组只能选一个,但是这样的背包问题又是与分组强相关的,那么怎么做呢?这道题、这道题和这道题就是这种分组背包的典范。这种背包问题的共同特征是:选完一组背包中的上一个后,才能选下一个。......