NOIP2005提高组复赛第二题详细解答

来源:百度知道 编辑:UC知道 时间:2024/05/18 02:03:53
【问题描述】

在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧。在桥上有一些石子,青蛙很讨厌踩在这些石子上。由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把独木桥上青蛙可能到达的点看成数轴上的一串整点:0,1,……,L(其中L是桥的长度)。坐标为0的点表示桥的起点,坐标为L的点表示桥的终点。青蛙从桥的起点开始,不停的向终点方向跳跃。一次跳跃的距离是S到T之间的任意正整数(包括S,T)。当青蛙跳到或跳过坐标为L的点时,就算青蛙已经跳出了独木桥。
题目给出独木桥的长度L,青蛙跳跃的距离范围S,T,桥上石子的位置。你的任务是确定青蛙要想过河,最少需要踩到的石子数。

【输入文件】

输入文件river.in的第一行有一个正整数L(1 <= L <= 109),表示独木桥的长度。第二行有三个正整数S,T,M,分别表示青蛙一次跳跃的最小距离,最大距离,及桥上石子的个数,其中1 <= S <= T <= 10,1 <= M <= 100。第三行有M个不同的正整数分别表示这M个石子在数轴上的位置(数据保证桥的起点和终点处没有石子)。所有相邻的整数之间用一个空格隔开。

【输出文件】

输出文件river.out只包括一个整数,表示青蛙过河最少需要踩到的石子数。

【样例输入】

10
2 3 5
2 3 5 6 7

【样例输出】

2

【数据规模】

对于30%的数据,L <= 10000;
对于全部的数据,L <= 109。

我是刚学信息学的OIER

但我很想知道NOIP2005提高组复赛第二题详细解答

我目前只知道这题可以用动态规划解(有一点动态规划的基础,能解简单的

动态规划题)但不知道具体的编写思路和细节。

我还听说如果两个石子之间的距离如果大于90就可以当作90来做,不知道为

什么。请给出详细的说明。

初步分析:

设f(i)表示到达坐标i时最少踩到的石子数。
r(i)表示坐标i上有无石子,若有,r(i)=1,否则r(i)=0
f(i)=min{f(j)}+r(i),其中s<=i-j<=t
边界f(0)=0
Ans=min{f(i)},其中i>=L

该算法时间复杂度是O(L*(t-s))

深入分析:
直观上说,对于一大片没有石子的区域,我们进行动态规划是没有必要的。
可以证明,当空白区域大于某个max的时候,青蛙一定可以从该区域的一端跳到另一端。
事实上,对于跳跃区间[s,t]来说,max<100
所以我们可以将每段长度>max的空白区域压缩成max的长度。这样总的L’就只有m*max<=10000。
这样再进行前面的动态规划,复杂度是O(L’*(t-s)),就可以在时限内出解了

此分析为NOIP2005全国唯一满分获得者(被保送北京大学):长沙市雅礼中学 姚金宇 给出

[问题分析]

此题初看是一个典型的搜索题。从河的一侧到河的另一侧,要找最少踩到的石头数。但从数据范围来看。1..109长度的桥。就算是O(n)的算法也不能在一秒内出解。

如果搜索石子,方法更困难。这要考虑到前面以及后面连续的石子。若换一种方法。用动态规划,以石子分阶段的一维动规,时间复杂度是O(n2)。最多也只有100×100的时间。但是这样分状态就十分复杂。因为石头的分布是没有任何规律,而且会有后效性。

这样只好有回到搜索。搜索石子会和动规一样没有规律。我们一桥的长度为对象进行搜索,然后再加上一个巧妙的剪枝就可以在很短的时间内出解。可以号称为O(m2)。[批注:号称一词已成为湖南OI本世纪流行词汇 ]

[题目实现]

先以时间为对象进行搜索。时间复杂度为O(L)。从桥的一侧到另一侧,中间最多只有100个石子。假设桥长为最大值(109),石头数也为最大值(100)。这样中间一定会有很多“空长条” (两个石子中的空地),处理时把这些跳过,就只