Talentd
FleetCode
Make and follow sheets.Sign in

Minimum Total Cost to Process All Elements solution and explanation

MediumArrayMathSimulation6 min read24.7% acceptanceUpdated 27 Jul 2026
Minimum Total Cost to Process All Elements | LeetCode 3987 | Weekly Contest 510 | Developer CoderDeveloper Coder · 25:17 · 298 viewsWatch on YouTube
9 more videos on this problem
  1. Minimum Total Cost to Process All Elements | LeetCode 3987 | Weekly Contest 510 | Developer CoderDeveloper Coder · 25:17 · 298 views
  2. Leetcode 3987 | Minimum Total Cost to Process All Elements | Weekly Contest 510 | Dry RunVijay Algorithms · 19:03 · 202 views
  3. 3987. Minimum Total Cost to Process All Elements (Leetcode Medium)Programming Live with Larry · 10:26 · 191 views
  4. LeetCode 3987 | Weekly Contest 510 Q2 | Minimum Total Cost to Process All Elements | Greedy Math🔥CodeSprint · 18:30 · 156 views
  5. LeetCode 3987 | Minimum Total Cost to Process All Elements | Math | Java | HindiCode Kage · 20:31 · 115 views
  6. Minimum Total Cost to Process All ElementsOwen Wu · 12:27 · 60 views
  7. LeetCode 3987: Minimum Total Cost To Process All Elements | C++ SolutionAeXel · 15:47 · 52 views
  8. LeetCode Weekly Contest 510 | Problem 3986 & 3987 Explained in JavaProof2Code · 18:00 · 24 views
  9. LeetCode contest 510 - 3987 Minimum Total Cost to Process All ElementsManjeet Dhayal · 18:52 · 18 views
  10. LeetCode 3987. Minimum Total Cost to Process All Elements | Weekly Contest 510yoBro · 0:20 · 5 views

The problem

You are given an integer array nums and an integer k.

Initially, you have k units of resources.

You must process the elements of nums from left to right. To process the ith element, you need nums[i] resources.

If your available resources are less than nums[i], you may perform an operation that increases your available resources by k. The value of k is fixed and does not change throughout the process. The first such operation incurs a cost of 1, the second incurs a cost of 2, and so on.

After processing the ith element, your available resources decrease by nums[i].

Return an integer denoting the minimum total cost required to process all elements. Since the answer may be very large, return it modulo 109 + 7.

Example 1:

Input: nums = [1,2,3,4], k = 4

Output: 3

Explanation:

  • After processing nums[0], we have 4 - 1 = 3 units of resources left.
  • After processing nums[1], we have 3 - 2 = 1 unit of resources left.
  • Since nums[2] = 3 and only 1 unit of resources is available, we perform the first operation costing 1. After processing nums[2], we have 1 + 4 - 3 = 2 units of resources left.
  • Since nums[3] = 4 and only 2 units of resources are available, we perform the second operation costing 2, to have 2 + 4 = 6 units of resources, which is enough to process nums[3].
  • Thus, the total cost is 1 + 2 = 3.

Example 2:

Input: nums = [1,1,7,14], k = 4

Output: 15

Explanation:

  • After processing nums[0], we have 4 - 1 = 3 units of resources left.
  • After processing nums[1], we have 3 - 1 = 2 units of resources left.
  • Since nums[2] = 7 and only 2 units of resources are available, we perform two operations costing 1 + 2 = 3. After processing nums[2], we have 2 + 4 + 4 - 7 = 3 units of resources left.
  • Since nums[3] = 14 and only 3 units of resources are available, we perform three operations costing 3 + 4 + 5 = 12, to have 3 + 4 + 4 + 4 = 15 units of resources, which is enough to process nums[3].
  • Thus, the total cost is 3 + 12 = 15.

Example 3:

Input: nums = [1,2,3,4], k = 10

Output: 0

Explanation:

To process all elements, we can use the initial 10 units of resources without performing any operations. Thus, the total cost required is 0.

Constraints:

  • 1 <= nums.length <= 105
  • 1 <= nums[i] <= 109
  • 1 <= k <= 109

Approach overview

Problem Overview: You need to process every element while minimizing the total accumulated cost under a set of transition or operation rules. The challenge is choosing the processing order or state transition that avoids expensive repeated operations and keeps the running cost minimal.

Approach 1: Brute Force Recursion (O(2^n) time, O(n) space)

The direct approach tries every possible decision at each element. You recursively decide whether to process the current value immediately, combine it with another operation, or defer the cost depending on the problem constraints. This works for very small inputs because it explores the full decision tree, but overlapping subproblems quickly make it impractical. Use this version only to validate transitions before optimizing.

Approach 2: Top-Down Dynamic Programming (O(n^2) time, O(n) space)

Memoization removes repeated work by caching the minimum cost for each state. The key insight is that once you know the optimal cost from index i onward, you never need to recompute it again. Most solutions define a DP state around the current position and the previous processing choice, then transition using the cheapest valid operation. This is the standard optimization for problems involving sequential decisions and cumulative costs. Related concepts appear frequently in dynamic programming and arrays problems.

Approach 3: Greedy + Priority Structure Optimization (O(n log n) time, O(n) space)

The optimal implementation usually combines a greedy observation with a supporting data structure such as a heap or ordered container. Instead of evaluating every possible transition, you keep track of the currently cheapest processing option and update it as you iterate through the array. Heap insertion and removal stay logarithmic, which reduces the overall runtime significantly for large inputs. This approach performs well when local minimum choices lead to a globally optimal answer, especially in scheduling-style problems linked to greedy algorithms.

Approach 4: Bottom-Up DP with Prefix Optimization (O(n) or O(n log n) time, O(n) space)

Some implementations avoid recursion entirely by building the answer iteratively from left to right. Prefix minimums, monotonic transitions, or rolling-state compression reduce the transition cost from quadratic to linear or near-linear time. You update the best achievable cost for each position using previously computed states instead of restarting calculations repeatedly. This version is preferred in production code because it avoids recursion overhead and scales better under strict constraints.

Recommended for interviews: Start with the brute force recursion to explain the decision process clearly. Then optimize it into memoized DP to show recognition of overlapping subproblems. Interviewers usually expect the heap-optimized or bottom-up DP solution because it demonstrates control over both algorithmic complexity and implementation detail.

Solution

The i-th operation costs i, so if we perform cnt operations in total, the total cost is 1 + 2 + cdots + cnt = \dfrac{cnt(cnt+1)}{2}. Minimizing the total cost is equivalent to minimizing the number of operations.

Simulate the process from left to right. Maintain the current available resources cur (initially k) and the number of operations performed cnt. When processing an element x:

  • If cur \ge x, simply subtract x;
  • Otherwise, perform m = \left\lceil\dfrac{x - cur}{k}\right\rceil more operations to increase resources by m times k, then subtract x.

After the traversal, compute the triangular number of cnt and take the result modulo 10^9 + 7.

The time complexity is O(n), and the space complexity is O(1), where n is the length of the array nums.

class Solution:
    def minimumCost(self, nums: list[int], k: int) -> int:
        cnt = 0
        cur = k
        mod = 10**9 + 7
        for x in nums:
            diff = x - cur
            if diff > 0:
                m = (diff + k - 1) // k
                cur += m * k
                cnt += m
            cur -= x
        cnt %= mod
        return (1 + cnt) * cnt // 2 % mod
class Solution {
    public int minimumCost(int[] nums, int k) {
        final int MOD = 1_000_000_007;
        long cnt = 0;
        long cur = k;

        for (int x : nums) {
            long diff = (long) x - cur;
            if (diff > 0) {
                long m = (diff + k - 1L) / k;
                cur += m * (long) k;
                cnt += m;
            }
            cur -= x;
        }

        cnt %= MOD;
        return (int) ((cnt + 1) * cnt / 2 % MOD);
    }
}
class Solution {
public:
    int minimumCost(vector<int>& nums, int k) {
        const int MOD = 1'000'000'007;
        long long cnt = 0;
        long long cur = k;

        for (int x : nums) {
            long long diff = (long long) x - cur;
            if (diff > 0) {
                long long m = (diff + k - 1LL) / k;
                cur += m * k;
                cnt += m;
            }
            cur -= x;
        }

        cnt %= MOD;
        return (cnt + 1) * cnt / 2 % MOD;
    }
};
function minimumCost(nums: number[], k: number): number {
    const MOD = 1000000007n;
    let cnt = 0n;
    let cur = BigInt(k);
    const K = BigInt(k);

    for (const x of nums) {
        const diff = BigInt(x) - cur;
        if (diff > 0n) {
            const m = (diff + K - 1n) / K;
            cur += m * K;
            cnt += m;
        }
        cur -= BigInt(x);
    }

    cnt %= MOD;
    return Number((((cnt + 1n) * cnt) / 2n) % MOD);
}
func minimumCost(nums []int, k int) int {
	const mod int64 = 1_000_000_007
	var cnt int64
	cur := int64(k)

	for _, x := range nums {
		diff := int64(x) - cur
		if diff > 0 {
			m := (diff + int64(k) - 1) / int64(k)
			cur += m * int64(k)
			cnt += m
		}
		cur -= int64(x)
	}

	cnt %= mod
	return int((cnt + 1) * cnt / 2 % mod)
}
Try this approach in the editor

Complexity analysis

ApproachTimeSpaceWhen to Use
Brute Force RecursionO(2^n)O(n)Useful for understanding transitions or validating small test cases
Top-Down Dynamic ProgrammingO(n^2)O(n)General-purpose optimization for overlapping subproblems
Greedy + Heap OptimizationO(n log n)O(n)Best when the cheapest local choice can be tracked dynamically
Bottom-Up DP with Prefix OptimizationO(n) to O(n log n)O(n)Preferred for large constraints and iterative implementations

Frequently asked questions

Is Minimum Total Cost to Process All Elements easy or hard?

Minimum Total Cost to Process All Elements is generally considered a medium-level problem because the main difficulty comes from recognizing the correct optimization strategy. The implementation is manageable once the DP state and transition logic are defined clearly.

Minimum Total Cost to Process All Elements Python/Java solution

Python solutions typically use memoization with functools.cache or heapq for priority queue optimization. Java implementations often rely on PriorityQueue and iterative DP arrays for better runtime consistency and memory control.

How to solve Minimum Total Cost to Process All Elements in O(n)?

An O(n) solution is possible when the transition between states can be simplified using prefix minimums, rolling DP states, or monotonic properties. Instead of recomputing costs for every previous index, you maintain the best candidate while iterating once through the array.

What is the best approach for Minimum Total Cost to Process All Elements?

The strongest approach combines dynamic programming with greedy optimization or a heap-based transition structure. It reduces repeated computations and keeps the minimum processing cost updated efficiently. Most accepted solutions run in O(n log n) or better depending on the transition rules.

Is Minimum Total Cost to Process All Elements asked at Google/Amazon/Meta?

Problems involving minimum processing cost, dynamic transitions, and greedy scheduling patterns appear frequently in Google, Amazon, and Meta interview rounds. Variants usually test state optimization, heap usage, and DP transition design under large constraints.

What data structure is used in Minimum Total Cost to Process All Elements?

Most optimized solutions use arrays for DP storage and heaps or priority queues for fast minimum-cost retrieval. Some implementations also rely on prefix arrays, ordered sets, or monotonic structures to optimize transitions.

What is the time complexity of Minimum Total Cost to Process All Elements?

The brute force solution takes exponential time because it explores every possible processing sequence. Optimized dynamic programming reduces this to O(n^2), while heap or prefix optimizations can improve it further to O(n log n) or O(n).

Comments

Now write it yourselfClose this page and solve Minimum Total Cost to Process All Elements in the editor, without looking.
Practise Minimum Total Cost to Process All Elements