过河

Description

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


题目给出独木桥的长度L,青蛙跳跃的距离范围S,T,桥上石子的位置。你的任务是确定青蛙要想过河,最少需要踩到的石子数。

Input

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

Output

对于每组测试数据,仅输出一行,包括一个整数,表示青蛙过河最少需要踩到的石子数。

Sample Input

10
2 3 5
2 3 5 6 7

Sample Output

2

根据其讲述,跳到第i个位置所踩的石头的最小数只与i-s~i-t这几个位置的数有关,所以可以联想到DP。 
但是发现L<=109

109,这个数据太大,直接dp会炸,所以想方法优化。当两个石头之间的距离大于t是中间一定会出现一部分没有踩到石子的空白地段,如果,因为s, t的范围比较小,而距离很长,石子也只有100个,所以两个石子之间的平均距离就很大,所以有一些石子之间的距离的空白地段可以去除,然后剩下的距离就很短,在10*101的范围了,因为理论上超过t就有可能有空白地段,所以最后剩下的距离是可以直接跑dp的。可是怎么确定缩短多少距离呢?我们每一个大于t的距离,假设距离为L,都可以由l+n*t得到,所以对于大于t的距离,我们可以进行取模,然后加上t,为什么要加上t,因为这样才能体现这段路径之前的状态,因为之前这段路是大于t的,我们只是通过去除空白快缩短距离,而不是改变它的状态,所以取模后加t是最小的未改变状态又缩短了距离的数值,缩短距离后,我们可以dp,状态转移方程为dp[i] = min(dp[i-j]+vis[i], dp[i]);因为过了河之后不是单纯一个点,而是一个范围,所以我们要一直更新到压缩之后的路径再加t,然后在那个范围内求最小。

代码如下:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值