Minimize the sum of product

Last Updated : 22 May, 2026

Given two arrays a[] and b[] of size n containing positive integers. Rearrange the elements of both arrays so that the value of: a[0] * b[0] + a[1] * b[1] + ... + a[n-1] * b[n-1] becomes minimum. Each element of a[] and b[] must be used exactly once.

Examples:

Input: a[] = [3, 1, 1], b[] = [6, 5, 4]
Output: 23
Explanation: After rearranging: a[] = [1, 1, 3] and b[] = [6, 5, 4]. Minimum sum = (1 * 6) + (1 * 5) + (3 * 4) = 6 + 5 + 12 = 23.

Input: a[] = [6, 1, 9, 5, 4] , b[] = [3, 4, 8, 2, 4]
Output: 80
Explanation: After rearranging: a[] = [1, 4, 5, 6, 9] and b[] = [8, 4, 4, 3, 2]. Minimum sum = (1 * 8) + (4 * 4) + (5 * 4) + (6 * 3) + (9 * 2) = 8 + 16 + 20 + 18 + 18 = 80.

Try It Yourself
redirect icon

[Naive Approach] Try All Permutations - O(n! × n!) Time O(n) Space

The idea is to generate all possible permutations of both arrays and evaluate every possible pairing. For each pair of permutations, we compute the sum of products and select the minimum among all results.

  • Generate all permutations of array a[]
  • Generate all permutations of array b[]
  • For every pair of permutations:
  • Compute sum: a[0]*b[0] + a[1]*b[1] + ... + a[n-1]*b[n-1]
  • Keep track of the minimum sum obtained.
C++
#include <bits/stdc++.h>
using namespace std;

// Function to calculate sum of products for a given arrangement
int calc(vector<int> &a, vector<int> &b) {
    int sum = 0;

    for (int i = 0; i < a.size(); i++) {
        sum = (sum + a[i] * b[i]);
    }

    return sum;
}

// Function to generate all permutations of array a[]
void permuteA(vector<int> &a, int idx, vector<vector<int>> &allA) {

    // Base case: if full permutation is formed
    if (idx == a.size()) {
        allA.push_back(a);
        return;
    }

    // Try swapping current index with all possible positions
    for (int i = idx; i < a.size(); i++) {
        swap(a[i], a[idx]);
        permuteA(a, idx + 1, allA);
        
        // backtrack
        swap(a[i], a[idx]); 
    }
}

// Function to generate all permutations of array b[]
void permuteB(vector<int> &b, int idx, vector<vector<int>> &allB) {

    // Base case: if full permutation is formed
    if (idx == b.size()) {
        allB.push_back(b);
        return;
    }

    // Try swapping current index with all possible positions
    for (int i = idx; i < b.size(); i++) {
        swap(b[i], b[idx]);
        permuteB(b, idx + 1, allB);
        
        // backtrack
        swap(b[i], b[idx]); 
    }
}

int minProductSum(vector<int> a, vector<int> b) {

    vector<vector<int>> allA, allB;

    // Generate all permutations of both arrays
    permuteA(a, 0, allA);
    permuteB(b, 0, allB);

    int res = INT_MAX;

    // Try every possible pairing of permutations
    for (auto &x : allA) {
        for (auto &y : allB) {
            res = min(res, calc(x, y));
        }
    }

    return res;
}

int main() {

    vector<int> a = {3, 1, 1};
    vector<int> b = {6, 5, 4};

    cout << minProductSum(a, b) << endl;

    return 0;
}
Java
import java.util.ArrayList;
import java.util.List;

class GFG {

    // Function to calculate sum of products for a given arrangement
    static int calc(int[] a, int[] b) {
        int sum = 0;

        for (int i = 0; i < a.length; i++) {
            sum = (sum + a[i] * b[i]);
        }

        return sum;
    }

    // Function to swap elements in array
    static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

    // Function to generate all permutations of array a[]
    static void permuteA(int[] a, int idx, List<int[]> allA) {

        // Base case: if full permutation is formed
        if (idx == a.length) {
            allA.add(a.clone());
            return;
        }

        // Try swapping current index with all possible positions
        for (int i = idx; i < a.length; i++) {
            swap(a, i, idx);
            permuteA(a, idx + 1, allA);

            // backtrack
            swap(a, i, idx);
        }
    }

    // Function to generate all permutations of array b[]
    static void permuteB(int[] b, int idx, List<int[]> allB) {

        if (idx == b.length) {
            allB.add(b.clone());
            return;
        }

        for (int i = idx; i < b.length; i++) {
            swap(b, i, idx);
            permuteB(b, idx + 1, allB);
            swap(b, i, idx);
        }
    }

    static int minProductSum(int[] a, int[] b) {

        List<int[]> allA = new ArrayList<>();
        List<int[]> allB = new ArrayList<>();

        // Generate all permutations
        permuteA(a, 0, allA);
        permuteB(b, 0, allB);

        int res = Integer.MAX_VALUE;

        // Try all combinations
        for (int[] x : allA) {
            for (int[] y : allB) {
                res = Math.min(res, calc(x, y));
            }
        }

        return res;
    }

    public static void main(String[] args) {

        int[] a = {3, 1, 1};
        int[] b = {6, 5, 4};

        System.out.println(minProductSum(a, b));
    }
}
Python
# Function to calculate sum of products for a given arrangement
def calc(a, b):
    sum = 0

    for i in range(len(a)):
        sum = (sum + a[i] * b[i])

    return sum


# Function to generate all permutations of array a[]
def permuteA(a, idx, allA):

    # Base case: if full permutation is formed
    if idx == len(a):
        allA.append(a[:])
        return

    # Try swapping current index with all possible positions
    for i in range(idx, len(a)):
        a[i], a[idx] = a[idx], a[i]
        permuteA(a, idx + 1, allA)

        # backtrack
        a[i], a[idx] = a[idx], a[i]


# Function to generate all permutations of array b[]
def permuteB(b, idx, allB):

    # Base case: if full permutation is formed
    if idx == len(b):
        allB.append(b[:])
        return

    # Try swapping current index with all possible positions
    for i in range(idx, len(b)):
        b[i], b[idx] = b[idx], b[i]
        permuteB(b, idx + 1, allB)

        # backtrack
        b[i], b[idx] = b[idx], b[i]

def minProductSum(a, b):

    allA = []
    allB = []

    # Generate all permutations of both arrays
    permuteA(a, 0, allA)
    permuteB(b, 0, allB)

    res = float('inf')

    # Try every possible pairing of permutations
    for x in allA:
        for y in allB:
            res = min(res, calc(x, y))

    return res


if __name__ == "__main__":

    a = [3, 1, 1]
    b = [6, 5, 4]

    print(minProductSum(a, b))
C#
using System;
using System.Collections.Generic;

class GFG {

    // Function to calculate sum of products for a given arrangement
    static int calc(List<int> a, List<int> b) {
        int sum = 0;

        for (int i = 0; i < a.Count; i++) {
            sum = (sum + a[i] * b[i]);
        }

        return sum;
    }

    // Function to generate all permutations of array a[]
    static void permuteA(List<int> a, int idx, List<List<int>> allA) {

        // Base case: if full permutation is formed
        if (idx == a.Count) {
            allA.Add(new List<int>(a));
            return;
        }

        // Try swapping current index with all possible positions
        for (int i = idx; i < a.Count; i++) {

            int temp = a[i];
            a[i] = a[idx];
            a[idx] = temp;

            permuteA(a, idx + 1, allA);

            // backtrack
            temp = a[i];
            a[i] = a[idx];
            a[idx] = temp;
        }
    }

    // Function to generate all permutations of array b[]
    static void permuteB(List<int> b, int idx, List<List<int>> allB) {

        // Base case: if full permutation is formed
        if (idx == b.Count) {
            allB.Add(new List<int>(b));
            return;
        }

        // Try swapping current index with all possible positions
        for (int i = idx; i < b.Count; i++) {

            int temp = b[i];
            b[i] = b[idx];
            b[idx] = temp;

            permuteB(b, idx + 1, allB);

            // backtrack
            temp = b[i];
            b[i] = b[idx];
            b[idx] = temp;
        }
    }

    static int minProductSum(List<int> a, List<int> b) {

        List<List<int>> allA = new List<List<int>>();
        List<List<int>> allB = new List<List<int>>();

        // Generate all permutations of both arrays
        permuteA(a, 0, allA);
        permuteB(b, 0, allB);

        int res = int.MaxValue;

        // Try every possible pairing of permutations
        foreach (List<int> x in allA) {
            foreach (List<int> y in allB) {
                res = Math.Min(res, calc(x, y));
            }
        }

        return res;
    }

    static void Main() {

        List<int> a = new List<int>() { 3, 1, 1 };
        List<int> b = new List<int>() { 6, 5, 4 };

        Console.WriteLine(minProductSum(a, b));
    }
}
JavaScript
// Function to calculate sum of products for a given arrangement
function calc(a, b) {
    let sum = 0;

    for (let i = 0; i < a.length; i++) {
        sum = (sum + a[i] * b[i]);
    }

    return sum;
}

// Function to generate all permutations of array a[]
function permuteA(a, idx, allA) {

    // Base case: if full permutation is formed
    if (idx === a.length) {
        allA.push([...a]);
        return;
    }

    // Try swapping current index with all possible positions
    for (let i = idx; i < a.length; i++) {

        [a[i], a[idx]] = [a[idx], a[i]];

        permuteA(a, idx + 1, allA);

        // backtrack
        [a[i], a[idx]] = [a[idx], a[i]];
    }
}

// Function to generate all permutations of array b[]
function permuteB(b, idx, allB) {

    // Base case: if full permutation is formed
    if (idx === b.length) {
        allB.push([...b]);
        return;
    }

    // Try swapping current index with all possible positions
    for (let i = idx; i < b.length; i++) {

        [b[i], b[idx]] = [b[idx], b[i]];

        permuteB(b, idx + 1, allB);

        // backtrack
        [b[i], b[idx]] = [b[idx], b[i]];
    }
}

function minProductSum(a, b) {

    let allA = [];
    let allB = [];

    // Generate all permutations of both arrays
    permuteA(a, 0, allA);
    permuteB(b, 0, allB);

    let res = Number.MAX_SAFE_INTEGER;

    // Try every possible pairing of permutations
    for (let x of allA) {
        for (let y of allB) {
            res = Math.min(res, calc(x, y));
        }
    }

    return res;
}

// Drive code
let a = [3, 1, 1];
let b = [6, 5, 4];
console.log(minProductSum(a, b));

Output
23

[Expected Approach] Sorting + Greedy - O(n log n) Time and O(1) Space

To minimize the sum of products, we minimize the contribution of larger elements. Since larger elements have a higher impact on the final result, they should be paired with smaller elements instead of other large elements.

To achieve this, we sort one array in increasing order and the other in decreasing order. This ensures that each large element is multiplied with a small element, which reduces its contribution and leads to the minimum possible sum of products.

  • Sort array a[] in increasing order.
  • Sort array b[] in decreasing order.
  • Initialize sum = 0.
  • Traverse both arrays: sum += a[i] * b[i]
  • Return sum.

Consider: a[] = {3, 1, 1} and b[] = {6, 5, 4}

Step 1: To minimize the sum, we first sort array a[] in increasing order and array b[] in decreasing order.

  • a[] = {1, 1, 3}
  • b[] = {6, 5, 4}

Step 2: Now, multiply elements at the same index of both arrays and compute the sum.

  • i = 0 -> 1 × 6 = 6
  • i = 1 -> 1 × 5 = 5
  • i = 2 -> 3 × 4 = 12

Total sum = 6 + 5 + 12 = 23

C++
#include <bits/stdc++.h>
using namespace std;

int minProductSum(vector<int> &a, vector<int> &b) {

    // Sort a[] in increasing order
    sort(a.begin(), a.end());

    // Sort b[] in decreasing order
    sort(b.begin(), b.end(), greater<int>());

    int sum = 0;

    // Multiply smallest element of a[]
    // with largest element of b[]
    for (int i = 0; i < a.size(); i++) {
        sum = sum + a[i] * b[i];
    }

    return sum;
}

int main() {

    vector<int> a = {3, 1, 1};
    vector<int> b = {6, 5, 4};

    cout << minProductSum(a, b) << endl;

    return 0;
}
Java
import java.util.Arrays;

class GFG {
    public static int minProductSum(int[] a, int[] b) {

        // Sort a[] in increasing order
        Arrays.sort(a);

        // Sort b[] in decreasing order
        Arrays.sort(b);

        // Reverse b[] to make it decreasing order
        for (int i = 0; i < b.length / 2; i++) {
            int temp = b[i];
            b[i] = b[b.length - 1 - i];
            b[b.length - 1 - i] = temp;
        }

        int sum = 0;

        // Multiply smallest element of a[]
        // with largest element of b[]
        for (int i = 0; i < a.length; i++) {
            sum = sum + a[i] * b[i];
        }

        return sum;
    }
    public static void main(String[] args) {

        int[] a = {3, 1, 1};
        int[] b = {6, 5, 4};

        System.out.println(minProductSum(a, b));
    }
}
Python
def minProductSum(a, b):

    # Sort a[] in increasing order
    a.sort()

    # Sort b[] in decreasing order
    b.sort(reverse=True)

    sum = 0

    # Multiply smallest element of a[]
    # with largest element of b[]
    for i in range(len(a)):
        sum = sum + a[i] * b[i]

    return sum


if __name__ == "__main__":

    a = [3, 1, 1]
    b = [6, 5, 4]

    print(minProductSum(a, b))
C#
using System;
using System.Collections.Generic;
using System.Linq;

class GFG {

    static int minProductSum(List<int> a, List<int> b) {

        // Sort a[] in increasing order
        a.Sort();

        // Sort b[] in decreasing order
        b = b.OrderByDescending(x => x).ToList();

        int sum = 0;

        // Multiply smallest element of a[]
        // with largest element of b[]
        for (int i = 0; i < a.Count; i++) {
            sum = sum + a[i] * b[i];
        }

        return sum;
    }

    static void Main() {

        List<int> a = new List<int>{3, 1, 1};
        List<int> b = new List<int>{6, 5, 4};

        Console.WriteLine(minProductSum(a, b));
    }
}
JavaScript
function minProductSum(a, b) {

    // Sort a[] in increasing order
    a.sort((x, y) => x - y);

    // Sort b[] in decreasing order
    b.sort((x, y) => y - x);

    let sum = 0;

    // Multiply smallest element of a[]
    // with largest element of b[]
    for (let i = 0; i < a.length; i++) {
        sum = sum + a[i] * b[i];
    }

    return sum;
}

// Driver code
let a = [3, 1, 1];
let b = [6, 5, 4];

console.log(minProductSum(a, b));

Output
23
Comment