离散化

离散化

转自(Matrix67

对于 什么是离散化 ,搜索帖子你会发现有各种说法,比如 排序后处理 对坐标的近似处理 等等。哪个是对的呢?哪个都对。关键在于,这需要一些例子和不少的讲解才能完全解释清楚。

离散相对于连续而言,连续通俗来讲指平滑的过渡,比如12 之间可以有无数的数,可以无限分割。而离散指数据的不连续性,比如123 。。。。这样画出的曲线是不连续的。

离散数学是数据结构的基础,其实是一切冯氏结构计算机的理论基础。

离散化是程序设计中一个非常常用的技巧,它可以有效的降低时间复杂度。其基本思想就是在众多可能的情况中 只考虑我需要用的值 。下面我将用三个例子说明,如何运用离散化改进一个低效的,甚至根本不可能实现的算法

《算法艺术与信息学竞赛》中的计算几何部分,黄亮举了一个经典的例子,我认为很适合用来介绍离散化思想。题目意思很简单,给定平面上n 个点的坐标,求能够覆盖所有这些点的最小矩形面积。这个问题难就难在,这个矩形可以倾斜放置(边不必平行于坐标轴)。

 

这里的倾斜放置很不好处理,因为我们不知道这个矩形最终会倾斜多少度。假设我们知道这个矩形的倾角是α ,那么答案就很简单了:矩形面积最小时四条边一定都 挨着某个点。也就是说,四条边的斜率已经都知道了的话,只需要让这些边从外面不断逼近这个点集直到碰到了某个点。你不必知道这个具体应该怎么实现,只需要理解这可以通过某种方法计算出来,毕竟我们的重点在下面的过程。

我们的算法很显然了:枚举矩形的倾角,对于每一个倾角,我们都能计算出最小的矩形面积,最后取一个最小值。

这个算法是否是正确的呢?我们不能说它是否正确,因为它根本不可能实现。矩形的倾角是一个实数,它有无数种可能,你永远不可能枚举每一种情况。我们说,矩形的倾角是一个 连续的 变量,它是我们无法枚举这个倾角的根本原因。我们需要一种方法,把这个 连续的 变量变成一个一个的值,变成一个 离散的 变量。这个过程也就是所谓的离散化。

我们可以证明,最小面积的矩形不但要求四条边上都有一个点,而且还要求至少一条边上有两个或两个以上的点。试 想,如果每条边上都只有一个点,则我们总可以把这个矩形旋转一点使得这个矩形变 ,从而有余地得到更小的矩形。于是我们发现,矩形的某条边的斜率必然与某两点的连线相同。如果我们计算出了所有过两点的直线的倾角,那么α 的取值只有可能是这些倾角或它减去90 度后的角(直线按“/” 方向倾斜时)这么 C(n,2) 种。我们说,这个 倾角 已经被我们 离散化 了。虽然这个算法仍然有优化的余地,但此时我们已经达到了本文开头所说的目的。

对于某些坐标虽然已经是整数(已经是离散的了)但范围极大的问题,我们也可以用离散化的思想缩小这个规模。最近搞模拟赛Vijos 似乎火了一把,我就拿两道Vijos 的题开刀。
VOJ1056(http://www.vijos.cn /Problem_Show.asp?id=1056)
永远是离散化的经典问题。大意是给定平面上的n 个矩形(坐标为整数,矩形与矩形之间可能有重叠的部分),求其覆盖的总面积。平常的想法就是开一个与二维坐 标规模相当的二维Boolean 数组模拟矩形的 覆盖 (把矩形所在的位置填上True )。可惜这个想法在这里有些问题,因为这个题目中坐标范围相当大 (坐标范围为-10^810^8 之间的整数)。但我们发现,矩形的数量n<=100 远远小于坐标范围。每个矩形会在横纵坐标上各 使用 两个值, 100 个矩形的坐标也不过用了-10^810^8 之间的200 个值。也就是说,实际有用的值其实只有这么几个。这些值将作为新的坐标值重新划分整个平 面,省去中间的若干坐标值没有影响。我们可以将坐标范围 离散化1200 之间的数,于是一个200*200 的二维数组就足够了。实现方法正如本文开 头所说的 排序后处理 。对横坐标(或纵坐标)进行一次排序并映射为12n 的整数,同时记录新坐标的每两个相邻坐标之间在离散化前实际的距离是多少。这 道题同样有优化的余地。

最后简单讲一下计算几何以外的一个运用实例(实质仍然是坐标的离散)。才考的 VOJ1238(http://www.vijos.cn/Problem_Show.asp?id=1238) 中,标程开了一个与时间范围一样大的数组 来储存时间段的位置。这种方法在空间上来看十分危险。一旦时间取值范围再大一点,盲目的空间开销将导致Memory Limit Exceeded 。我们完全可以采用离散化避免这种情况。我们对所有给出的时间坐标进行一次排序,然后同样用时间段的开始点和结束点来计算每个时刻的游戏数,只是一次性加的经验值数将乘以排序后这两个相邻时间点的实际差。这样,一个1..n 的数组就足够了。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值