绳索燃烧算法

时间:2014-10-29 01:20:44

标签: algorithm dynamic-programming

从技术面试问题推广:

  

原始问题:有两根绳子,每根绳子需要1小时   烧伤。但是,任何一根绳子在不同的点都有不同的密度,所以   在不同的时间内无法保证一致性   绳索内的部分要燃烧。

     

你如何使用这两根绳子测量45分钟?

我有一个通用版本:

  

有n条绳索,每条绳索需要x分钟   刻录(为简单起见,假设x是正整数)。但绳索在不同的点有不同的密度,所以   在不同的时间内无法保证一致性   绳索中的部分要燃烧。

     

使用这些n绳索,您可以测量的时间量是多少?

     

例如,当n = 1且x = 60时,我可以测量60分钟的时间段   (烧一根绳子),或30分钟(燃烧两端)   同时绳索)

当然,我的目标是找到一种复杂度最低的算法。我想这个解决方案涉及动态编程,但我不太确定。我的蛮力解决方案如下:

  1. 从第0分钟开始,我们有n条绳索,每条需要x分钟才能燃烧。对于给定的绳索,我们可以选择燃烧两端,一端或根本不燃烧绳索。让在这个阶段不燃烧的绳索数量为x,将一端燃烧的绳索数量为y,并且根本不燃烧的绳索数量为z。我们有x + y + z = n,x,y,z是正整数,z!= 0.考虑x,y和z的所有可能情况,并将这些情况添加到堆栈/队列。
  2. 对于堆叠/队列中的每个项目,确定绳索完成刻录时已经过了多少分钟。输出已经过去的时间(根据完成的绳索燃烧多长时间计算,以及在什么时间燃烧哪一端)。现在我们有另外一些场景,其中有一定数量的绳索被烧毁。使用x + y + z = n - 1重复步骤1参数(对x,y和z施加约束,因为某些绳索仍在刻录,我们无法设置关闭)并将所有新生成的案例添加到堆栈/队列中。
  3. 重复2.直到n = 0(所有绳索完成燃烧)
  4. 编辑: 对于n = 2和x = 60,我发现可以测量以下时间段:30,60,90,120,45和15。

    正如所建议的那样,我在cs.stackexchange.com上发布了这个问题:https://cs.stackexchange.com/questions/32455/algorithm-for-rope-burning-problem

1 个答案:

答案 0 :(得分:1)

嗯,这是我尝试以更高的效率解决问题。我可能忽略了某些东西,所以即使它似乎有意义也要小心。

我们可以从1根绳索的基础状态开始x分钟或x / 2分钟。现在,假设可以使用x_prev绳索测量n分钟。然后,考虑如果我们添加n+1绳索会发生什么。我们可以

  1. 等待整个x_prev分钟到期,然后从1端烧掉下一根绳子。这意味着我们可以实现x_prev + x分钟。
  2. 等待整个x_prev分钟到期,然后从2端烧掉下一根绳子。这意味着我们可以达到x_prev + x/2分钟。
  3. 当我们从1端烧掉下一根绳子时,开始燃烧x_prev分钟。这意味着我们可以实现abs( x - x_prev )分钟。
  4. 当我们从两端烧掉下一根绳子时,开始燃烧x_prev分钟。这意味着我们可以达到abs( x/2 - x_prev)分钟。
  5. 我们不关心t使用m绳索实现的时间m<=n-1因为我们在添加m+1-th绳索时会考虑这四种情况

    这些似乎只有四个案例。所以,在伪代码中,也许是这样的

    let solutions be a list of measurable times
    def solve( n , x ):
        if n <= 0
             return, you cannot measure any times
        else
             #set up base case n=1
             append x/2 and x to solutions
    
             #we can be efficient by only checking the times achievable with n-1 ropes
             #we will store the index of the first time that was recorded with n-1 ropes
             #in start_idx
             let start_idx be an index in the solutions array
    
             #assume the array indices start at 0. then start_idx is the index
             #of the first recorded time measurable with 1 rope.
             start_idx = 0
    
             #then continuously add additional ropes until we have n ropes
             for i in 2..n
    
                  let solutions_to_add be a list
    
                  for j in start_idx..solutions.size() - 1
                       if solutions does not contain time+x
                            append time+x to solutions_to_add
                       if solutions does not contain time+x/2
                            append time+x/2 to solutions_to_add
                       if solutions does not contain abs( x-time )
                            append abs( x-time ) to solutions_to_add
                       if solutions does not contain abs( x/2-time )
                            append abs( x/2-time ) to solutions_to_add
    
                  #update the start_idx to be the starting index of times achievable with
                  #i ropes
                  start_idx = solutions.size()
    
                  #then add the achievable times with i ropes
                  for each time in solutions_to_add
                       append time to solutions
    

    通过使用布尔数组进行查找,您可以获得solution contains的O(1)运行时间。整体算法似乎是O(n ^ 2)。

    这是对的吗?我不确定我的四个案例是否涵盖了所有内容。我很确定类似感应的过程是正确的。