Add All#1228

Add All (Editorial)

Each time, two smallest numbers should be added together. This way, the total cost of adding all integers will be minimized. Since numbers can repeat, it is convenient to store them in a multiset.

Example

To minimize the cost of addition, add the numbers in the following order:

  1. Add and to get . Cost of addition is .

  2. Add and to get . Cost of addition is .

  3. Add and to get . Cost of addition is .

The total cost of addition is 3 + 6 + 10 = 19.

Algorithm implementation

The input numbers are stored in a multiset (numbers can repeat). The two smallest numbers are always located at the beginning of the multiset.

multiset<long long> s;

Read the number of elements .

scanf("%lld",&n);

Read the sequence of numbers and add them to the multiset .

for (i = 0; i < n; i++)
{
  scanf("%lld",&x);
  s.insert(x);
}

The total cost of adding all numbers is computed in the variable .

res = 0;

While there is more than one number in the multiset , extract and add the two smallest elements, then add their sum back into . The cost of adding numbers and is a + b, and this cost is added to .

while (s.size() > 1)
{
  a = *s.begin(); s.erase(s.begin());
  b = *s.begin(); s.erase(s.begin());
  s.insert(a + b);
  res += a + b;
}

When only one number remains in the multiset, print the answer — the value of the variable .

printf("%lld\n",res);

Algorithm implementation — priority queue

Declare a priority queue , where the smallest element is always at the front.

priority_queue<long long, vector<long long>, greater<long long> > pq;

Read the number of elements .

scanf("%lld",&n);

Read the sequence of numbers and add them to the priority queue .

scanf("%lld",&n);
for (i = 0; i < n; i++)
{
  scanf("%lld",&x);
  pq.push(x);
}

The total cost of adding all numbers is computed in the variable .

res = 0;

While there is more than one number in the priority queue , extract and add the two smallest elements, then add their sum back into . The cost of adding numbers and is a + b, and this cost is added to .

while (pq.size() > 1)
{
  a = pq.top(); pq.pop();
  b = pq.top(); pq.pop();
  pq.push(a + b);
  res += a + b;
}

When only one number remains in the priority queue, print the answer – the value of the variable .

printf("%lld\n",res);

Java implementation

import java.util.*;

public class Main
{
  public static void main(String[] args)
  {
    Scanner con = new Scanner(System.in);
    int n = con.nextInt();
    PriorityQueue<Long> pq = new PriorityQueue<Long>();
    for(int i = 0; i < n; i++)
    {
      long val = con.nextLong();
      pq.add(new Long(val));
    }
    long Result = 0;
    while(pq.size() > 1)
    {
      long a = pq.poll();
      long b = pq.poll();
      pq.add(a + b);
      Result += a + b;
    }
    System.out.println(Result);    
  }
}

Python implementation

Declare a priority queue , where the smallest element is always at the front.

from queue import PriorityQueue
q = PriorityQueue()

Read the input data.

n = int(input())
lst = map(int,input().split())

Add the numbers to the queue .

for x in lst:
  q.put(x)

The total cost of adding all numbers is computed in the variable .

res = 0

While there is more than one number in the priority queue , extract and add the two smallest elements, then add their sum back into . The cost of adding numbers and is a + b, and this cost is added to .

while q.qsize() > 1:
  a = q.get()
  b = q.get()
  q.put(a + b)
  res += a + b

When only one number remains in the priority queue, print the answer — the value of the variable .

print(res)