假设我有一辆有N辆货车的火车。每辆旅行车i
都有n_i
个单元格,而每个单元格有6个座位。
现在假设0&lt; x <= 6名乘客进入我们列车的i
旅行车,并希望坐在同一个牢房里。我想找到第一个合适的单元格,在最坏的情况下O(log*n)
有足够的空闲席位。
系统初始化最多可能需要O(n)
。
n =火车中的细胞总数。
我试图用6 *(货车数量)不相交的集合来解决这个问题,但是我很难保持这种复杂的解决方案。
PS:log*n
是迭代对数。
答案 0 :(得分:0)
希望这不是一个无意识的遗漏,我的解决方案让新来的乘客在火车车厢里小步走。毕竟,在问题描述中没有写出他们会在他们进入的马车中找到自己的座位。并且乘客的行走复杂性不会对算法的复杂性造成不利影响;)
以下数据类型以及数据的组织方式就足够了。 索引成员就是这样我们也可以在新乘客到达时通过数据结构跟踪细胞。类型Cell也可以简单地为int(货车标识符,也仅仅是信息)。
type Cell = { Index : int; Wagon : int }
现在,我们根据列表数列出我们的问题。数组的大小为7(单元格中有0..6个空位)。
我们从空车开始。因此所有单元格都在列表中,存储在数组索引6处(6个空位=空单元格)。
当x乘客到达[1..6]时,我们所要做的就是测试数组[x]到数组[6]是非空的。第一个非空列表包含我们想让乘客填充的单元格。
由于现在该单元格中的空位是oldVacancies(数组索引) - x,我们将单元格添加到数组[oldVacancies - x]中的列表中。
该算法应该满足问题的复杂性要求......至少。
这是F#中的示例实现:
module Trains =
type Cell = { Index : int; Wagon : int }
type Problem = List<Cell> []
let init ncells cellsPerWagon =
let initCells =
[ for i in 0..(ncells-1) do yield { Index = i; Wagon = i % cellsPerWagon } ]
Array.init 7 (fun i -> if i = 6 then initCells else [] )
let arrival (nPassengers : int) (problem : Problem) : Problem option =
let rec findCell (index : int) : (Cell * int) option =
if index > 6 then None
else
match problem.[index] with
| [] -> findCell (index+1)
| c::cs ->
problem.[index] <- cs
Some(c,index)
match nPassengers with
| 0 -> Some(problem)
| x when x > 6 -> None
| _ ->
let maybeFound = findCell nPassengers
match maybeFound with
| Some(cell,vacancies) ->
problem.[vacancies - nPassengers] <- cell :: problem.[vacancies - nPassengers]
Some(problem)
| None -> None