题解 | #过河#

过河

http://www.nowcoder.com/practice/35ddfeb4e34f410bb9035682463a382f

对python来说,本题真正的难点在于l很大时如何不超时。 为此需要运用数论做一些粗浅的算法优化。

实际上还有很多能抠的细节没有抠,因为在python上的运行速度已经比较令人满意了,再去深究一些不能改变运算量数量级的地方意义不大。

注:由irises1412提供的答案应该是错误的,它通不过示例自测。

# 对python来说,本题真正的难点在于l很大时如何不超时。
l = int(input())
s, t, m = list(map(int, input().split()))
sts = list(map(int, input().split()))
sts = sorted(sts)

# 化简原问题来减少计算量:假设位置为i,j的两个石头之间的距离 j-i > 2*s*t,
# 那么实际上跳到第j个位置最少踩的石头数量就等于跳到第j-s*t个位置最少踩的石头数量。
# 于是在l很大时,计算量从O(l)减少到O(s*t*m)
sts = [0] + sts + [l]
for i in range(1, m + 2):
    d = sts[i] - sts[i - 1]
    if d > 2 * s * t:
        r = d % (s * t)
        if r == 0:
            minus = d - 2 * s * t
        else:
            minus = d - r - s * t
        sts[i : m + 2] = [sts[j] - minus for j in range(i, m + 2)]
sts, l = sts[1:-1], sts[-1]

# 动态规划:这里建立了长度为t的动态规划列表,但可读性和速度可能不如用长度为新l的列表。
# 初始化动态规划
dp = [float("inf") for _ in range(t)]
dp[0] = 0
for i in range(1, t):
    choice = dp[max(0, i - t) : max(0, i - s + 1)]
    if choice:
        dp[i] = min(choice) + (i in sts)

# 进行动态规划
for i in range(t, t + l):
    choice = dp[: t - s + 1]
    if choice:
        dp = dp[1:] + [min(choice) + (i in sts)]
    else:
        dp = dp[1:] + [float("inf")]

print(min(dp))

全部评论

相关推荐

不愿透露姓名的神秘牛友
07-08 13:15
点赞 评论 收藏
分享
06-15 02:05
已编辑
南昌航空大学 数据分析师
Eason三木:你如果想干技术岗,那几个发公众号合唱比赛的经历就去掉,优秀团员去掉,求职没用。然后CET4这种不是奖项,是技能,放到下面的专业技能里或者单独列一个英语能力。 另外好好改改你的排版,首行缩进完全没有必要,行间距好好调调,别让字和标题背景黏在一起,你下面说能做高质量PPT你得展现出来啊,你这简历排版我用PPT做的都能比你做的好。 然后自我评价,你如果要干数据工程师,抗压能力强最起码得有吧。
简历中的项目经历要怎么写
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务