当前位置:首页 > 枚举 > 正文
SSOJ1278守望者的逃离(NOIP2007)
2248+

题目大意:走路每秒17米,用魔法每秒60米,但同时消耗10魔法值,休息一秒积累4魔法值,t秒钟能走m米吗?如果能,至少花多少时间?如果不能,最远走多远?

题目描述

恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变。守望者在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上。为了杀死守望者,尤迪安开始对这个荒岛施咒,这座岛很快就会沉下去。到那时,岛上的所有人都会遇难。守望者的跑步速度为17m/s,以这样的速度是无法逃离荒岛的。庆幸的是守望者拥有闪烁法术,可在1s内移动60m,不过每次使用闪烁法术都会消耗魔法值10点。守望者的魔法值恢复的速度为4点/s,只有处在原地休息状态时才能恢复。

现在已知守望者的魔法初值M,他所在的初始位置与岛的出口之间的距离S,岛沉没的时间T。你的任务写写一个程序帮助守望者计算如何在最短的时间内逃离荒岛,若不能逃出,则输出守望者在剩下的时间能走的最远距离。注意:守望者跑步、闪烁或休息活动均以秒(s)为单位,且每次活动的持续时间为整数秒。距离的单位为米(m)。

输入

在输入文件escape.in仅一行,包括空格隔开的三个非负整数M,S,T。

输出

在输出文件escape.out包括两行:

第1行为字符串“Yes”或“No”(区分大小写),即守望者是否能逃离荒岛。

第2行包含一个整数。第一行为“Yes”(区分大小写)时表示守望者逃离荒岛的最短时间;

第一行为“No”(区分大小写)时表示守望者能走的最远距离。

样例输入

【输入样例1】
39 200 4

【输入样例2】
36 255 10

样例输出

【输出样例1】
No
197

【输出样例2】
Yes
6

提示

30%的数据满足:1< =T< =10,1< =S< =100

50%的数据满足:1< =T< =1000,1< =S< =10000

100%的数据满足:1< =T< =300000,0< =M< =1000,1< =S< =108

NOIP2007普及组第三题

解题思路

每秒钟要么休息,要么走路,要么使用魔法值,暴力搜索至少可得30分!

不难发现,走路跟使用魔法值的顺序是可以调换的。比如我有足够的魔法值,我使用魔法值再走路,和走一段路再用魔法值,其实是等价的。使用魔法最多用300000次,如果已知使用魔法的次数,那么走路的次数也确定了,可以直接算出来耗时和最远走到哪。我们可以枚举使用魔法的次数,计算出对应的耗时和距离,记录最优值即可。

程序实现

注意:代码12行,需要加上条件“y < s”,表示还需要走路。如果不需要走路,就不能走路了,不然可能导致距离变远,后面用魔法多走了路,导致时间变短。

代码第6行加3、第12行加16是为了向上取整。

爆搜40分:dfs表示走到a,耗时c,魔法值是b,对于每个位置的状态,我们可以很方便地记录最远距离、最快到达的时间。时间复杂度是O(2^n)。

代码第10行,用了贪心剪枝,因为魔法值足够了,肯定用魔法比较快,这是显然的。

记忆化剪枝满分:f[a][b]表示走到a魔法值是b的最远距离,如果后面发现距离重复或者更小剪枝,因为剩下的时间是固定的,魔法值相同的情况下,后面的最优值是固定的。

注意:代码第16和17行不能调换,因为记忆化剪枝,跟值的顺序有很大联系。先用魔法值会走得远些,后面再走路,没那么容易超越,可以让距离进来不要变大,减少重复搜索。

时间复杂度O(t*10*s),搜索的顺序能影响s的范围。

贪心剪枝满分:到底走路还是使用魔法,我们可以计算一下,发现如果有7秒,即使魔法值为0,使用魔法也能走120米(5秒休息2秒魔法),如果只是走路就只能走17*7=119米。

因此,在魔法值小于10的情况下,如果数据达到7秒,路程剩下超过120米,休息肯定没错的。对于剩下7秒钟,暴力就行。时间复杂度O(t + 2^7)。

SSOJ1278守望者的逃离(NOIP2007):等您坐沙发呢!

发表评论

您必须 [ 登录 ] 才能发表留言!