为什么这个代码适用于这个TopCoder问题?

时间:2012-04-27 18:10:55

标签: java algorithm huffman-code

我一直试图从HOURS开始考虑这个TopCoder问题并且无法找到一个完美的解决方案,并且发现下面给出的一个非常精美的使用!

我想弄清楚这个解决方案如何适用于给定的探测器?我怎么能原先想到它?在阅读了解决方案之后,我认为它是霍夫曼编码的一种变体,但这是我能得到的。我真的很着迷,想知道什么样的思路可以导致这个解决方案..

这是问题所在: http://community.topcoder.com/stat?c=problem_statement&pm=11860&rd=15091

  

Fox Ciel有很多功课要做。作业由一些人组成   相互独立的任务。不同的任务可能需要不同的金额   时间来完成。你得到一个int [] workCost。对于每个我,   第i个任务需要workCost [i]秒才能完成。她想   参加一个聚会,并结识她的朋友,因此她想完成所有   任务尽快完成。

     

主要问题是包括Ciel在内的所有狐狸都非常讨厌这样做   家庭作业。每只狐狸只愿意做其中一项任务。幸运的是,   哆啦A梦,一个来自22世纪的机器人猫,给了福克斯Ciel一个分裂   锤子:一个魔法小工具,可以将任何狐狸分成两只狐狸。

     

给你一个int splitCost。在狐狸上使用分裂锤是   瞬间。一旦在狐狸上使用锤子,狐狸就会开始   分裂。在分秒成本后,她将变成两只狐狸 -   原来的狐狸和另一只全新的狐狸。当狐狸分裂时,   不允许再次使用锤子。

     

任务的工作不能中断:一旦狐狸开始工作   一项任务,她必须完成它。多只狐狸不允许这样做   合作完成同样的任务。狐狸不能在任务中工作   用锤子分开。可以分割同一只狐狸   多次。可以在前后分割狐狸   她解决了其中一项任务。

     

计算并返回狐狸可以的最短时间   解决所有任务。

这是我在link

找到的解决方案
import java.util.*; 

public class FoxAndDoraemon { 
  public int minTime(int[] workCost, int splitCost) { 
    PriorityQueue<Integer> pq = new PriorityQueue<Integer>(); 

    for(int i : workCost) pq.offer(i); 

    while(pq.size()>=2) { 
      int i = pq.poll(); 
      int j = pq.poll(); 
      pq.offer(Math.max(i, j) + splitCost); 
    } 
    return pq.poll(); 

  } 
}

2 个答案:

答案 0 :(得分:6)

首先,你会意识到`max(i,j)+ splitCost'背后的原因。不是吗?基本上,如果你有一只狐狸,你将它分成两只并独立完成每项任务。让我们称这个过程为“合并”。

现在假设我们有三个作业a,b和c,使得&gt; b&gt; c。您可以合并(合并(a,b),c)或合并(合并(a,c),b)或合并(合并(b,c),a)。算一算,你可以证明合并(merge(b,c),a)在这三者中最少。

您现在可以使用归纳来证明此解决方案适用于任意数量的作业(而不仅仅是3)。

答案 1 :(得分:3)

它正在从头开始建造一棵树。

该算法使用一个基本事实: 如果删除两个最小元素,计算最小元素的成本总是小于下一个最小元素的成本加上一个分割。 (请参阅ElKamina的帖子,以获得更为全面的证据)。

因此,如果您的树中只有两个元素(比如4和2),并且您的拆分成本为4,那么最短的时间总是为8(最小元素的下一个加上拆分成本。< / p>

所以,构建我们的树:假设我们得到了workCost [1,3,4,5,7,8,9,10],而我们的splitCost是3。

因此,我们看看两个最小的元素:1,3。计算这些的“成本”至少为6(最大数量加上拆分成本。然后将6重新插入队列,你实际上是在添加子树:

  6
1   3

'身高'/'成本'总共为6。通过重复此过程,您将使用最小的子元素(现有子树或新的未完成的作业)构建树。

解决方案最终将如下所示:(其中S(X)是拆分的成本加上解决其下的所有内容)

                  S(17)
            S(13)       S(14)
       S(10)     9   10      S(11)
  S(6)      7            S(8)     8
1     3                 4    5

如果向后追溯这棵树,很容易看出公式如何解决它:1和3的成本是S(6),4和5是S(8),那么S(6)和7是S(10),8和S(8)是S(11)等。