首页 > 其他分享 >动态规划(Ⅲ)

动态规划(Ⅲ)

时间:2023-07-10 15:11:45浏览次数:39  
标签:倍增 优化 db pos da 动态 规划 DP

前言

这部分主要讲一讲 DP 优化的一些方法,显然我的实力不太够,所以只能写一些比较简单的东西。

动态规划(Ⅰ)中提到的,动态规划的优化一般就可以从两个方面入手:一个是状态表示、另一个是决策集合,也就是状态转移的角度来优化。下文主要就是分别从这两个角度,阐述不同的 DP 优化方法。

倍增优化 DP

倍增优化 DP,是从状态表示的方面来进行 DP 优化。简单来说,因为动态规划经常采用按阶段的递推形式实现,所以也可以按照类似的方法,使用倍增把阶段的线性增长优化为成倍增长,也就是把一段 \(\mathcal O(n)\) 的部分优化成 \(\mathcal O(\log n)\),显然,优化效果显著。

下面给一道例题来讲一下倍增优化 DP 的方式。

例题

P1081 [NOIP2012 提高组] 开车旅行

题面太长了就不放了。

这道题 \(70\) 分代码是比较好写的,建议先写一下 \(70\) 分的 \(\mathcal O(n^2)\) 做法:

维护四个数组 \(city_1[i],city_2[i],dis_1[i],dis_2[i]\),分别表示距离城市 \(i\) 最近的城市,次近的城市,以及它们分别到城市 \(i\) 的距离。我们朴素地暴力 \(\mathcal O(n^2)\) 便能解决这个问题。

然后对于两个问题,我们便运用这四个数组,\(O(nm)\) 的枚举即可,没啥难度。
code

然后我们考虑怎么优化,其实这个题我感觉不像是一个真正的 DP,因为你一旦确定了起点,其实你的路径就是固定的了,而正是因为这个性质,使得我们可以采用倍增的方法来优化我们的复杂度。


倍增优化 DP

想要倍增优化,我们就考虑我们想知道什么:行驶到了哪座城市、小 A 行驶的路程、小 B 行驶的路程。根据这个,我们设出倍增 DP 的数组:

下文中,\(k=0\) 代表小 A 开车,\(k=1\) 代表小 B 开车。

设 \(f_{i,j,k}\) 表示从城市 \(j\) 出发,行驶 \(2^i\) 天,\(k\) 先开车,最终会到达的城市;

设 \(da_{i,j,k}\) 表示从城市 \(j\) 出发,行驶 \(2^i\) 天,\(k\) 先开车,小 A 行驶的路程;

设 \(db_{i,j,k}\) 表示从城市 \(j\) 出发,行驶 \(2^i\) 天,\(k\) 先开车,小 B 行驶的路程。

假设我们已经知道了暴力解法中的四个数组的值,我们考虑怎么求倍增数组。

初值的设定:

f[0][i][0] = city2[i], f[0][i][1] = city1[i];
da[0][i][0] = dis2[i], da[0][i][1] = 0;
db[0][i][0] = 0 ,db[0][i][1] = dis1[i];

结合数组意义应该不难看懂,接下来,我们按照预处理倍增数组的一般思路,递增第一维。

需要注意的是,当 \(i=1\) 时,我们从 \(i=0\) 扩展而来,这时候司机是变了一个人的;而当 \(i>1\) 时,我们从 \(i-1\) 转移而来,这时第 \(2^i\) 天和 \(2^{i-1}\) 天都是偶数,是由同一个人转移而来,所以要分类讨论一下。

当 \(i=1\) 时:

f[1][j][k] = f[0][f[0][j][k]][k ^ 1];
da[1][j][k] = da[0][j][k] + da[0][f[0][j][k]][k ^ 1];
db[1][j][k] = db[0][j][k] + db[0][f[0][j][k]][k ^ 1];

当 \(i>1\) 时:

f[i][j][k] = f[i - 1][f[i - 1][j][k]][k];
da[i][j][k] = da[i - 1][j][k] + da[i - 1][f[i - 1][j][k]][k];
db[i][j][k] = db[i - 1][j][k] + db[i - 1][f[i - 1][j][k]][k];

求解问题

朴素的求解问题是一步一步模拟走过的城市。有了倍增数组后,我们自然就可以进行倍增跳步了。具体实现如下:

  • 我们给定 \(pos=0,disA = 0 ,disB= 0\),分别表示现在在哪个城市,小 A 的路程,小 B 的路程。

  • 令 \(i\) 从 \(\log n\) 枚举到 \(0\),判断 \(f_{i,pos,0}\) 是否越界,并且 \(disA + disB + da_{i,pos,0} + db_{i,pos,0} \leq x\) 是否成立。如果不越界且成立,那么就直接令 \(pos=f_{i,pos,0},disA += da_{i,pos,0},disB += db_{i,pos,0}\),这也就实现了我们的跳步操作。

第二步结束后,\(disA\) 和 \(disB\) 就可以求出来了,有了这个,问题 \(1,2\) 就都很好解决了,我们就可以在 \(\mathcal O(n\log n)\) 的时间下解决问题。

dis = disA = disB = 0 , pos = i;
for(re int j=18;j>=0;j--)
{
	if(f[j][pos][0] != n+1 && disA + disB + da[j][pos][0] + db[j][pos][0] <= x)
	{
		disA += da[j][pos][0];
		disB += db[j][pos][0];
		pos = f[j][pos][0];
	}
}

解决根源的初始化

其实我们发现,我们还漏了一个地方,也就是那四个数组的初始化其实还是 \(\mathcal O(n^2)\) 的,但因为这个地方的优化跟倍增没有关系,所以放到最后来说。

具体来说,我们维护一个 multiset,存储节点编号和节点高度,初始时我们插入 \(4\) 个边界,两个 \(-\inf\),两个 \(\inf\),然后我们从右向左将每个城市插入进去,然后利用 multiset \(\mathcal O(\log n)\) 的查询它的前驱,前驱的前驱,后继,后继的后继,然后取一个最小值和次小值即可。(multiset 里面按高度从小到大排序)。

这样一来,初始化也是 \(\mathcal O(n\log n)\) 的了,综上,我们运用倍增优化 DP,就在 \(\mathcal O((n+m)\log n)\) 解决了这个问题。

code

此外的例题还有 AcWing294.计算重复,这里有两种倍增的手法,但其中一种更为优秀,具体可以看第一篇题解。

总结

倍增优化 DP 其实感觉不怎么像是 DP,因为能使用倍增 DP 的前提是,每个路线是已经确定的了,是静态的。当然这其中也有 DP 的思想,因为我们设的倍增数组其实就是 DP 的体现。

数据结构优化 DP

标签:倍增,优化,db,pos,da,动态,规划,DP
From: https://www.cnblogs.com/bloodstalk/p/17541221.html

相关文章

  • 无人车轨迹规划,利用代价函数求解最优轨迹,matlab程序 这
    无人车轨迹规划,利用代价函数求解最优轨迹,matlab程序这个程序是一个用于车辆导航和避障的示例。它使用了一种基于目标函数和障碍函数的规划方法,通过计算不同方向上的函数值来选择最佳移动方向,并模拟车辆在真实环境中移动的过程。程序的主要功能是模拟车辆在给定的区域内避开障碍物......
  • 动态创建style标签 写入样式
    //从字符串初始化documentconstparser=newDOMParser()constparseDocument=parser.parseFromString(this.editorText,'text/html')//动态创建style标签写入样式conststyle=parseDocument.createElement('style')sty......
  • 规划高速公路上完全可再生动力充电站:数据驱动的鲁棒优化方
    规划高速公路上完全可再生动力充电站:数据驱动的鲁棒优化方法本文提出了一种全面的两级方法,用于在公路网络上采用和大化独立电动电动机充电站。在第一阶段,从提供交通需求和电池数据的MonteCarlo仿真获得单个车辆需要充电服务的位置;提出了一种整数编程模型,以确定来自潜在候选者的......
  • 平行泊车、垂直泊车matlab程序仿真,效果不错,实现泊车路线规划。
    平行泊车、垂直泊车matlab程序仿真,效果不错,实现泊车路线规划。含部分参考说明ID:88150632200073070......
  • 如何实现jQuery实现id模糊查询动态id多个的具体操作步骤
    jQuery实现id模糊查询动态id多个引言在前端开发过程中,我们经常需要操作多个具有类似id的元素。如果我们想要通过id来选择这些元素,一种常见的做法是使用通配符和正则表达式来匹配符合条件的id。这篇文章将介绍如何使用jQuery来实现id模糊查询,并选择多个符合条件的元素。使用jQuer......
  • 2023ACM暑假训练day 11 动态规划
    目录DAY11动态规划训练情况简介题题题题DAY11动态规划训练地址:传送门训练情况简介2023-07-1009:30:17星期一早上:下午:晚上:题题意:思路:题题意:思路:题题意:思路:题题意:思路:......
  • AE 制作简单动态壁纸
    成品B站链接WallpaperEngine可用:搜索Alice_StarCried简述参考了B站的两个自学教程,都是直接搜能搜到的。PS、AE零基础。因为需要渲染所用电脑配置有一定需求,额外用了数位板。AE使用了现成脚本。从学习到制作完成总用时不过四天。所需技能为PS基本使用,包括抠图、补图等,......
  • 根据模板动态生成word(一)使用freemarker生成word
    @目录一、准备模板1、创建模板文件2、处理模板2.1处理普通文本2.2处理表格2.3处理图片二、项目代码1、引入依赖2、生成代码三、验证生成word一、准备模板1、创建模板文件首先先建立一个word文件,输入模板内容freemaker的内容,下面是本次演示的word文件。然后将word文件另存......
  • 动态规划
    动态规划做题步骤:状态表示:dp表中每一个格子所表示的意义。状态转移方程:dp[i]等于什么。初始化:保证填表不越界。填表顺序:为了填写当前格子,它需要的数据已经准备好。返回值:根据题目要求和状态表示返回结果。第n个泰波那契数:链接:https://leetcode.cn/problems/n......
  • 动态库单独添加Address Sanitizer
    原文地址:https://www.cnblogs.com/liqinglucky/p/address-sanitizer-in-library.htmlAddressSanitizer集成的原理是在汇编过程中(参考:程序编译过程与运行时内存-liqinglucky-博客园(cnblogs.com))编译出.o文件时就将AddressSanitizer的运行时库替换malloc()/free()实现内存......