【问题标题】:Dynamic Programming: Number of Seating Arrangements动态规划:座位安排的数量
【发布时间】:2021-01-06 10:55:43
【问题描述】:

这是我最近采访的一家公司提出的问题。前提是,电影院必须遵循距离规则,即每两个坐着的人之间必须有至少六英尺的距离。我们得到一个包含 N 个非负整数的列表,其中 list[k] 是座位 k 和座位 k + 1 之间的距离,单排有 N+1 个座位。我们需要弄清楚有效座位安排的数量。

编辑:经过深思熟虑,这就是我目前得到的结果

def count(seats):
    # No seats then no arrangements can be made
    if seats == 0:
        return 0
    elif seats == 1:
        # 1 seat means 2 arrangements -- leave it empty (skip) or occupy it
        return 2
    
    if list[seats-1] < 6:
       return count(seats - 1) + counts(seats - k(seats))
    else:
       return count(seats - 1)

回想一下,list 将包含座位 i 和座位 i+1 之间的距离,因此在每个座位上,我都会检查当前座位与前一个座位之间的距离是否 >= 6 或 = 6,所以无论我是否占用当前座位,我的子问题座位数都会缩小一个。

【问题讨论】:

  • 如果您可以分享您在代码中采用的方法,这可能会有所帮助。
  • @peacetype 我想多了。请问现在可以看一下吗?

标签: recursion dynamic-programming memoization


【解决方案1】:

您可以使用two pointer technique 和动态规划来解决这个问题。
这里 dp[i] 代表有效组合的数量,其中第 i 个座位是最后一个使用的座位(最后 -> 最大索引)。

代码:

def count(distances):
    pref_dist = answer = 0
    pos = pos_sum = pos_dist = 0
    dp = [1] * (len(distances) + 1)
    for i in range(len(distances)):
        pref_dist += distances[i]
        while(pref_dist - pos_dist >= 6):
            pos_dist += distances[pos]
            pos_sum += dp[pos]
            pos += 1
        dp[i + 1] += pos_sum
    return sum(dp) + 1

时间复杂度:
它是O(n),其中n 是座位数(不是O(n^2))因为while 条件在整个代码执行中最多为n 次(指针pos 永远不会减少,每次条件为true 那么pos 加一并且pos 上限是n) 并且其中的每个操作都使用恒定的时间。

示例:

  1. 六个座位和距离阵列 [5, 2, 4, 1, 2]
    计数([5, 2, 4, 1, 2]) -> 16
    这些是有效的组合(1 表示采取):
    000000 101000 000010 100001
    100000 000100 100010 010001
    010000 100100 010010 001001
    001000 010100 000001 101001

  2. 四个座位和距离阵列 [8, 10, 16]
    计数([8, 10, 6]) -> 16
    每个组合都是有效的组合。四个座位 => 2^4 组合。

【讨论】:

    猜你喜欢
    • 2022-10-25
    • 1970-01-01
    • 1970-01-01
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-13
    相关资源
    最近更新 更多