简体   繁体   English

对于这个,有什么比蛮力更好的解决方案?

[英]What is a better solution than brute force for this?

Given a finite sequence of positive integers between [0-5] lets say [0,3,1,5,2,4,4,4] and a starting sequence [0,0,0,0,0,0,0,0]. 给定[0-5]之间有限的正整数序列,假设[0,3,1,5,2,4,4,4]和起始序列[0,0,0,0,0,0,0 ,0]。 We now want to build our given sequence from the starting sequence by performing stepwise operations. 我们现在想要通过执行逐步操作从起始序列构建我们给定的序列。 In one step, we can either increase all numbers from our starting sequence by 1 or increase just one index from this sequence by 1. Once we would increase a 5 in this case it would become a 0. 在一个步骤中,我们可以将起始序列中的所有数字增加1,或者将此序列中的一个索引增加1.一旦我们在这种情况下增加5,它将变为0。

What is the most efficient way to find the solution that requires the least steps? 找到需要最少步骤的解决方案的最有效方法是什么? This solution should of course also apply to other inputs (length + upper bound). 这个解决方案当然也应该适用于其他输入(长度+上限)。 For the starting sequence we can assume it is always 0 for each index. 对于起始序列,我们可以假设每个索引始终为0。

The brute force approach could look like this. 蛮力方法看起来像这样。

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);

Results: 结果:

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

I'm going to provide a way to decrement target original array (call it A ) to make [0,0,0,0...] , either by decrementing everything or decrementing individual items. 我将提供一种方法来减少目标原始数组(称之为A )以生成[0,0,0,0...] ,方法是递减所有内容或递减单个项目。 This of course is the same question, but with the steps in reverse. 这当然是同样的问题,但反过来的步骤。

First, calculate the cost for decrementing all the elements one-by-one. 首先,计算逐个递减所有元素的成本。 Call this cost CMAX and the length of the array N . 将此成本称为CMAX和数组N的长度。 CMAX = sum_for_all_i(A[i]) CMAX = sum_for_all_i(A [i])

Then sort the array, and find each position i where i=0 or A[i] > A[i-1] . 然后对数组进行排序,并找到每个位置i,其中i = 0A [1]> A [I-1]。

For each such position it's easy to calculate the cost that would result from decrementing everything until A[i] reaches 0, and then decrementing one-by-one. 对于每个这样的位置,很容易计算在A [i]达到0之前减少所有内容所产生的成本, 然后逐个递减。 It's easy, because we know that everything at index < i will wrap around, and everything with index >= i will not. 这很容易,因为我们知道索引<i的所有内容都会回滚,而索引> = i的所有东西都不会。 So: 所以:

COST(i) = CMAX + A[i] - A[i] * (Ni) + i*(UPPER_BOUND+1-A[i]) COST(i)= CMAX + A [i] - A [i] *(Ni)+ i *(UPPER_BOUND + 1-A [i])

The A[i] is the cost of all the global decrements. A [i]是所有全局减量的代价。 The - A[i] * (Ni) is the cost reduction for all the high elements that don't wrap around, and the cost i*(UPPER_BOUND+1-A[i]) is the increased cost for all the elements that wrap around from 0 to UPPER_BOUND . -A [i] *(Ni)是所有不包裹的高元素的成本降低,成本i *(UPPER_BOUND + 1-A [i])是所有元素的成本增加从0UPPER_BOUND回绕

The lowest COST you find (including CMAX ) is your answer. 您找到的最低成本 (包括CMAX )就是您的答案。 Total complexity is O(N log N) , dominated by the sort. 总复杂度为O(N log N) ,由排序主导。 If the upper bound is guaranteed to be small, then you can use a counting sort for that and get O(N+k) 如果上限保证很小,那么你可以使用计数排序并得到O(N + k)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 什么是比蛮力更好的算法来分隔重叠类别的项目? - What is a better algorithm than brute force to separate items in overlapping categories? 寻找比蛮力算法更好的算法 - Finding a better than Brute Force algorithm 比Neutreeko中的强力发电机更好地移动发电机 - Better move generator than brute force in Neutreeko 比抛硬币游戏的蛮力算法更好 - Better than brute force algorithms for a coin-flipping game 递归计算pow(x,n)比蛮力好吗? - Is recursively computing pow(x, n) better than brute force? 了解 KMP 解决方案 - 蛮力 - Understanding KMP solution - Brute Force 如何从字典中构建一个Plinko单词板比蛮力更好? - How to build a Plinko board of words from a dictionary better than brute force? 在找到最近的位置时,我怎么能比蛮力更好? - How can I do better than brute force in finding closest location? 谁能告诉我这个问题的更好解决方案? 我只能想到O(n ^ 2)的蛮力方式 - Could anyone tell me a better solution for this problem? I could only think of brute force way which is O(n^2) 为什么我的蛮力(O((n1 + n2)log(n1 + n2)))解决方案比优化解决方案(O(n1 + n2))更快? - why is my brute force(O((n1+n2)log(n1+n2))) solution faster than the optimised solution(O(n1+n2))?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM