有什么比蛮力更好的解决方案呢?

时间:2019-02-08 12:45:37

标签: algorithm performance brute-force

给出[0-5]之间的正整数的有限序列 让我们说[0,3,1,5,2,4,4,4]和一个起始序列[0,0,0,0,0,0,0,0]。 现在,我们要通过执行逐步操作从起始序列构建给定序列。 第一步,我们可以将起始序列中的所有数字都增加1,也可以将这个序列中的一个索引仅增加1。 在这种情况下,一旦我们增加5,它就会变成0。

找到需要最少步骤的解决方案的最有效方法是什么?当然,此解决方案也应适用于其他输入(长度+上限)。对于起始序列,我们可以假设每个索引始终为0。

蛮力方法看起来像这样。

int upperBound = 5;
int[] endSequence = {0,3,1,5,2,4,4,4};
int currentBestSteps = Integer.MAX_VALUE;
int currentTimesIncreaseAll = 0;

for(int start = 0;start <= upperBound;start++){ //how many times to increase all
  //counter how many steps required total, starting with start amount of steps
  //since we increase all values 'start' times  
  int counterSteps = start; 

  //go through all end values and calc how many steps required  
  for(int end:endSequence){ 
    if(start <= end){
      counterSteps += end-start;
    }else{
      counterSteps += end+upperBound+1-start;
    }
  }

  System.out.println("solution: increase all "+start+
                     " times, total steps: "+counterSteps);

  if(counterSteps < currentBestSteps){
    currentBestSteps = counterSteps;
    currentTimesIncreaseAll = start;
  }
}
System.out.println("best solution: increase all "+currentTimesIncreaseAll+
                   " times, total steps: "+currentBestSteps);

结果:

solution: increase all 0 times, total steps: 23
solution: increase all 1 times, total steps: 22
solution: increase all 2 times, total steps: 21
solution: increase all 3 times, total steps: 20
solution: increase all 4 times, total steps: 19
solution: increase all 5 times, total steps: 30
best solution: increase all 4 times, total steps: 19

1 个答案:

答案 0 :(得分:3)

我将提供一种减少目标原始数组(称为 A )以制作[0,0,0,0...]的方法,方法是减少所有内容或减少单个项目。当然,这是相同的问题,但是步骤相反。

首先,计算所有元素逐个递减的成本。将此成本称为 CMAX ,并将数组的长度称为 N CMAX = sum_for_all_i(A [i])

然后对数组进行排序,并找到每个位置 i ,其中 i = 0 A [i]> A [i-1]

对于每个这样的职位,很容易计算出将所有东西递减直到 A [i] 达到0,然后然后逐一递减所产生的成本。这很容易,因为我们知道索引为 的所有内容都会环绕,而索引为> = i 的所有内容都不会环绕。所以:

成本(i)= CMAX + A [i]-A [i] *(N-i)+ i *(UPPER_BOUND + 1-A [i])

A [i] 是所有全局减量的成本。 -A [i] *(Ni)是所有不环绕的高元素的成本降低,以及成本 i *(UPPER_BOUND + 1-A [i] )是从 0 UPPER_BOUND 的所有元素增加的成本。

您发现的最低 COST (包括 CMAX )就是您的答案。总复杂度为 O(N log N),由排序决定。如果保证上限较小,那么您可以为此使用计数排序并获得 O(N + k)