DSA sheet / Introductory

Increasing Array

easy about 12 min greedyoverflow
Open on CSES

Do these first: Repetitions

The problem in brief

You get an array of n integers (n up to 200 000, values up to 10^9). In one move you may add 1 to any element. Print the minimum number of moves needed so that no element is smaller than the one before it.

Try it

Tab indents; press Esc, then Tab, to leave the box. Ctrl+Enter runs.

Hints

Stuck? Reveal one hint at a time. Each nudges without giving away the next.

The walkthrough

Spoilers ahead: open a section only after you have given the hints a fair try.

How to think

Start with an exchange argument. Suppose the array is 5, 2. You can only add, so the 2 must rise to at least 5, and raising it to exactly 5 is enough. Raising the 5 would be pointless because it would only make the second element need even more. The generalisation: the first element never needs to change, and each later element only needs to be lifted to the current running maximum.

That is the shape of a greedy solution: a local choice (lift to the minimum allowed) that you can prove never hurts the future. The proof habit is worth learning: “if I chose something bigger, could I always shrink it back down without breaking anything?”. Here yes.

Intuition

Picture a staircase you are only allowed to build up, never dig down. Walking left to right, the staircase height is the tallest step so far; any step that is lower gets padded with bricks up to that height. Count the bricks.

Approach
  1. Keep top, the largest value seen so far, starting with the first element.
  2. For each next element x: if x < top, add top - x to the answer (lift x to top); otherwise set top = x.
  3. Print the total.

Pitfalls: the total can reach about 200 000 * 10^9 = 2 * 10^14, far over 32 bits, so use 64-bit. An array with one element needs zero moves.

Complexity

O(n) time, O(1) extra memory (you can even avoid storing the array).

Solutions

Written from scratch and checked by compiling and running each one against a brute force on random inputs. Fast input/output, the way you would submit it.

Show solutions (C++17, Python 3, Java 17, Node.js)
#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin >> n;
    long long top = 0, moves = 0;
    for (int i = 0; i < n; i++) {
        long long x;
        cin >> x;
        if (i == 0 || x >= top) top = x;
        else moves += top - x;
    }
    cout << moves << "\n";
    return 0;
}

Problem: CSES Problem Set (Antti Laaksonen, University of Helsinki), CC BY-NC-SA 4.0. The explanations and code above are original (© Anupam Kumar).

Related problems

Back to the sheet