这个DP解决方案是如何接近的?

时间:2012-04-28 04:47:27

标签: c++ algorithm dynamic-programming

我一直在尝试解决这个TopCoder问题,我现在无法想出基于DP的解决方案(如下所示)。我也找到了其他人解决问题的解决方案(下面也给出了解决方案),但我甚至无法理解它。

有人可以帮我解决这个问题吗?我不明白哪种思路会导致这种解决方案?我如何在脑海中建立复发关系?我完全不知道如何解决这个问题,或者编写该解决方案的人如何编写它。

PS:我知道TopCoder有关于问题的社论,但这个问题还没有发布。我不知道为什么。

这是problem

  

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

     

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

     

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

     

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

     

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

这是solution

1:    
2:  const int maxN = 55;  
3:  int dp[maxN][maxN*2];  
4:  int N;  
5:  int splitC;  
6:  vector<int> workC;  
7:    
8:  int rec(int,int);  
9:  int FoxAndDoraemon::minTime(vector <int> workCost, int splitCost) {  
10:      
11:    sort(workCost.begin(), workCost.end());  
12:    N = workCost.size();  
13:    splitC = splitCost;  
14:    workC = workCost;  
15:       memset(dp, -1, sizeof(dp));  
16:      
17:    return rec(N-1, 1);  
18:  }  
19:    
20:  int rec(int jobs, int fox)  
21:  {  
22:    if(jobs == -1) return 0;  
23:      
24:    int& val = dp[jobs][fox];  
25:    if(val != -1) return val;  
26:    val = 0;  
27:      
28:    if( (jobs+1) <= fox) val = max(workC[jobs] , rec(jobs-1, fox-1));  
29:    else  
30:    {  
31:      //split fox  
32:      val = splitC + rec(jobs, fox + 1);  
33:        
34:      if( !(fox == 1 && jobs > 0) )  
35:        val = min(val, max(workC[jobs], rec(jobs-1, fox-1)));  
36:    }  
37:    return val;  
38:  }  
39:    

2 个答案:

答案 0 :(得分:1)

DP问题通常需要你制定几个例子,而唯一的方法就是练习。尝试解决DP中的一些标准问题类型,如最长增加子序列,背包,硬币更改,矩阵乘法,TSP等。尝试这些类型的变量。

至于上述问题,很少有注意事项:

  • 你需要N只狐狸来完成N个任务(1只狐狸只能完成1项任务)。所以,如果你已经克隆了N狐,你就不需要再创造了。而且,如果你有超过1个任务,你必须拆分第一只狐狸。
  • 每只狐狸你可以做两件事
    • 将其拆分,然后计算所需的最短时间
    • 不要拆分,而是执行当前任务并计算用少量狐狸执行剩余任务所需的时间。
      • 请注意,如果您有超过1个Fox(或1个Fox有1个任务),您只能选择不拆分。

这可以让您了解问题。我还没有彻底分析过这个问题,但是递归似乎没有产生重叠的调用,即如果我有3个任务和2个狐狸,我只会调用那个状态一次而不是更多。因此,解决方案是常规的递归解决方案,而不是DP。

答案 1 :(得分:0)

社论现在在TopCoder网站上。你可以看看那里!