Building Construction#10869

Building Construction (Editorial)

Sort the buildings by height so that h_1 \le h_2 \le ... \le h_n. Buildings with the same heights are sorted by increasing cost of adding / removing.

Find the cost for which we can make the height of all houses equal to h_x~(1 \le x \le n). It is equal

f(x) = \sum_{i=1}^n |h_i - h_x| \cdot c_i

The function is concave and has a global minimum, that can be found with a ternary search.

Example

Consider the first example. Sort buildings by height:

Find the value of the function for all heights:

The minimum of the function is achieved at x = 3, while f(3) = 110.

Algorithm implementation

Each building has a height and the cost of adding or removing a floor. The information about all buildings is stored in the array .

#define MAX 100001
struct Building
{
  int h, cost;
};
Building b[MAX];

The function cmp is a comparator for sorting buildings. Buildings are sorted by increasing height. If the heights of the buildings are the same, then sort them by increasing cost.

int cmp(Building a, Building b)
{
  if (a.h == b.h)
    return a.cost < b.cost;
  return a.h < b.h;
}

The function f computes the cost to make all buildings equal to the height of the building number .

long long f(int x)
{
  long long ret = 0;
  for (int i = 1; i <= n; i++)
    ret += 1LL * abs(b[x].h - b[i].h) * b[i].cost;
  return ret;
}

The function ternary_search uses the ternary search to find the value of x \in [left; right] for which is minimal. Initially, the search range is [left; right] = [1; n].

long long ternarySearch(int left, int right)
{
  while (right - left >= 3)
  {
    int a = left + (right - left) / 3;
    int b = left + 2 * (right - left) / 3;
    if (f(a) > f(b))
      left = a;
    else
     right = b;
  }

The difference between and does not exceed . In this case, the minimum of on the interval [left; right] is found by exhaustive search.

  long long res = f(left++);
  while (left <= right)
    res = min(res, f(left++));
  return res;
}

The main part of the program. Read the input data.

scanf("%d", &n);
for (i = 1; i <= n; i++)
  scanf("%d", &b[i].h);
for (i = 1; i <= n; i++)
  scanf("%d", &b[i].cost);

Sort the buildings.

sort(b + 1, b + n + 1, cmp);

Find and print the answer. Buildings are numbered from to .

printf("%lld\n", ternarySearch(1, n));