无法理解二元搜索功能

时间:2017-11-02 15:19:45

标签: c++ binary-search

帮助我理解二元搜索在此问题中的用法: Problem

  

使用getMostWork方法编写一个类FairWorkload,该方法采用int []文件夹(每个文件柜的文件夹数)和int worker(工作者数)。该方法应返回一个int,这是工作人员在文件柜的最佳分区中必须查看的最大文件夹数量。

代码是

int getMostWork( vector  folders, int workers ) {
    int n = folders.size();
    int lo = *max_element( folders.begin(), folders.end() );
    int hi = accumulate( folders.begin(), folders.end(), 0 );

    while ( lo < hi ) {
      int x = lo + (hi-lo)/2;

      int required = 1, current_load = 0;
      for ( int i=0; i<n; ++i ) {
         if ( current_load + folders[i] <= x ) {
            // the current worker can handle it
            current_load += folders[i];
         }
         else {
            // assign next worker
            ++required;
            current_load = folders[i];               
         }
      }

      if ( required <= workers )
         hi = x;
      else
         lo = x+1;
    }

    return lo;
}

我没有得到这个部分:

 if ( required <= workers )
    hi = x;
 else
    lo = x+1;

有人可以解释一下这段代码吗?

2 个答案:

答案 0 :(得分:0)

Here binary search is being used to find the optimal solution.For binary search you need a range represented by high and low.You know the optimal answer lies within this range.In this particular problem low is represented by the minimum number of folders that a worker will have to look for, which is going to be the maximum number of folders in a cabinet

int lo = *max_element( folders.begin(), folders.end() );

The high would be if only one worker is assigned all folders which would be sum of all values in folders

int hi = accumulate( folders.begin(), folders.end(), 0 );

Now you loop through this range and try to find the optimal answer.

 while ( lo < hi ) {
      int x = lo + (hi-lo)/2;

In each iteration of the loop you check the number of workers required if each worker was given maximum x folders. You then decide the next range by checking if you were able to satisfy the constraint with x as solution and try to get more optimal solution

if ( required <= workers )
     hi = x;

If x is the solution, then i need required workers which is less than or equal to the workers, so i will try to get more optimal by having a lower value of maximum number of folders assigned to a worker.To do this you change the range to [lo,x]

 else
lo = x+1;

On the contrary if you need more workers than present, you will increase the range to [x+1,hi]

答案 1 :(得分:0)

首先提取中间函数:

int CountRequiredWorkers(const std::vector<int>& folders, int load) {
    int required = 1, current_load = 0;
    for (int i = 0; i < n; ++i) {
        if (current_load + folders[i] <= x) {
            // the current worker can handle it
            current_load += folders[i];
        } else {
            // assign next worker
            ++required;
            current_load = folders[i];               
        }
    }
    return required;
}

int getMostWork(const vector<int>& folders, int workers) {
    int n = folders.size();
    int lo = *max_element( folders.begin(), folders.end() );
    int hi = accumulate( folders.begin(), folders.end(), 0 );

    while ( lo < hi ) {
      const int mid = lo + (hi-lo)/2;
      const int required = CountRequiredWorkers(mid);

      if (required <= workers)
         hi = mid;
      else
         lo = mid + 1;
    }
    return lo;
}

所以我们对&#34;虚拟&#34;进行二元搜索。索引是总工作的数组,值是工作计数。有效索引是从最大的文件夹到所有文件夹的总和 该数组看起来像{N, N - 1, N - 1, ..., 2, 2, 1},我们想要第一个索引< workers