Open In App

Minimum number of operations to convert a given sequence into a Geometric Progression | Set 2

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] consisting of N integers, the following three operations can be performed on any element one at a time:

  • Add one to the element.
  • Subtract one from the element.
  • Leave the element unchanged.

The task is to find the minimum cost required to convert it into a Geometric Progression and also find the common ratio
Note: Each addition and subtraction operation costs 1 unit.

Examples: 

Input: N = 6, arr[] = {1, 11, 4, 27, 15, 33}
Output: 28 2
Explanation: 
For r = 1, arr[] = {1, 4, 11, 15, 27, 33} 
expected[] = {1, 1, 1, 1, 1, 1} 
cost[] = {0, 3, 10, 14, 26, 32} 
Total cost: ? cost = 85

For r = 2, arr[] = {1, 4, 11, 15, 27, 33} 
expected[] = {1, 2, 4, 8, 16, 32} 
cost[] = {0, 2, 7, 7, 11, 1}
Total cost: ? cost = 28
For r = 3, arr[] = {1, 4, 11, 15, 27, 33} 
expected[] = {1, 3, 9, 27, 81, 243} 
cost[] = {0, 1, 2, 12, 54, 210}
Total cost: ? cost = 279

Minimum cost = 28
Common ratio = 2

Input: N = 7, arr[] = {1, 2, 4, 8, 9, 6, 7}
Output: 30 1

Approach: The idea is to iterate over range of possible common ratios and check for the minimum operations required. Follow the steps below to solve the problem:

  • Sort the array.
  • Find the range of possible common ratios using the formula Ceil( arr[maximum_element] / (N – 1)).
  • Calculate the number of operations required for all possible common ratios.
  • Find the minimum operations required for any of the common ratios.

Below is the implementation of the above approach:

C++




// C++ program for above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find minimum cost
void minCost(int arr[], int n)
{
    if (n == 1) {
        cout << 0 << endl;
        return;
    }
 
    // Sort the array
    sort(arr, arr + n);
 
    // Maximum possible common ratios
    float raised = 1 / float(n - 1);
    float temp = pow(arr[n - 1], raised);
    int r = round(temp) + 1;
 
    int i, j, min_cost = INT_MAX;
    int common_ratio = 1;
 
    // Iterate over all possible common ratios
    for (j = 1; j <= r; j++) {
        int curr_cost = 0, prod = 1;
 
        // Calculate operations required
        // for the current common ratio
        for (i = 0; i < n; i++) {
 
            curr_cost += abs(arr[i] - prod);
            prod *= j;
            if (curr_cost >= min_cost)
                break;
        }
 
        // Calculate minimum cost
        if (i == n) {
            min_cost = min(min_cost,
                           curr_cost);
            common_ratio = j;
        }
    }
 
    cout << min_cost << ' ';
    cout << common_ratio << ' ';
}
 
// Driver Code
int main()
{
    // Given N
    int N = 6;
 
    // Given arr[]
    int arr[] = { 1, 11, 4, 27, 15, 33 };
 
    // Function Calling
    minCost(arr, N);
 
    return 0;
}


Java




// Java program for
// the above approach
import java.util.*;
class GFG{
 
// Function to find minimum cost
static void minCost(int arr[],
                    int n)
{
  if (n == 1)
  {
    System.out.print(0 + "\n");
    return;
  }
 
  // Sort the array
  Arrays.sort(arr);
 
  // Maximum possible common ratios
  float raised = 1 / (float)(n - 1);
  float temp = (float)Math.pow(arr[n - 1],
                               raised);
  int r = (int)(temp) + 1;
 
  int i, j, min_cost = Integer.MAX_VALUE;
  int common_ratio = 1;
 
  // Iterate over all possible
  // common ratios
  for (j = 1; j <= r; j++)
  {
    int curr_cost = 0, prod = 1;
 
    // Calculate operations required
    // for the current common ratio
    for (i = 0; i < n; i++)
    {
      curr_cost += Math.abs(arr[i] -
                            prod);
      prod *= j;
      if (curr_cost >= min_cost)
        break;
    }
 
    // Calculate minimum cost
    if (i == n)
    {
      min_cost = Math.min(min_cost,
                          curr_cost);
      common_ratio = j;
    }
  }
 
  System.out.print(min_cost + " ");
  System.out.print(common_ratio + " ");
}
 
// Driver Code
public static void main(String[] args)
{
  // Given N
  int N = 6;
 
  // Given arr[]
  int arr[] = {1, 11, 4,
               27, 15, 33};
 
  // Function Calling
  minCost(arr, N);
}
}
 
// This code is contributed by shikhasingrajput


Python3




# Python3 program for above approach
import sys
 
# Function to find minimum cost
def minCost(arr, n):
     
    if (n == 1):
        print(0)
        return
 
    # Sort the array
    arr = sorted(arr)
 
    # Maximum possible common ratios
    raised = 1 / (n - 1)
    temp = pow(arr[n - 1], raised)
    r = round(temp) + 1
 
    min_cost = sys.maxsize
    common_ratio = 1
 
    # Iterate over all possible
    # common ratios
    for j in range(1, r + 1):
        curr_cost = 0
        prod = 1
 
        # Calculate operations required
        # for the current common ratio
        i = 0
        while i < n:
            curr_cost += abs(arr[i] - prod)
            prod *= j
             
            if (curr_cost >= min_cost):
                break
             
            i += 1
 
        # Calculate minimum cost
        if (i == n):
            min_cost = min(min_cost,
                          curr_cost)
            common_ratio = j
 
    print(min_cost, common_ratio)
 
# Driver Code
if __name__ == '__main__':
     
    # Given N
    N = 6
 
    # Given arr[]
    arr = [ 1, 11, 4, 27, 15, 33 ]
 
    # Function calling
    minCost(arr, N)
 
# This code is contributed by mohit kumar 29


C#




// C# program for
// the above approach
using System;
 
class GFG{
 
// Function to find minimum cost
static void minCost(int []arr,
                    int n)
{
  if (n == 1)
  {
    Console.Write(0 + "\n");
    return;
  }
 
  // Sort the array
  Array.Sort(arr);
 
  // Maximum possible common ratios
  float raised = 1 / (float)(n - 1);
  float temp = (float)Math.Pow(arr[n - 1],
                               raised);
  int r = (int)(temp) + 1;
 
  int i, j, min_cost = int.MaxValue;
  int common_ratio = 1;
 
  // Iterate over all possible
  // common ratios
  for (j = 1; j <= r; j++)
  {
    int curr_cost = 0, prod = 1;
 
    // Calculate operations required
    // for the current common ratio
    for (i = 0; i < n; i++)
    {
      curr_cost += Math.Abs(arr[i] -
                            prod);
      prod *= j;
       
      if (curr_cost >= min_cost)
        break;
    }
 
    // Calculate minimum cost
    if (i == n)
    {
      min_cost = Math.Min(min_cost,
                          curr_cost);
      common_ratio = j;
    }
  }
 
  Console.Write(min_cost + " ");
  Console.Write(common_ratio + " ");
}
 
// Driver Code
public static void Main(String[] args)
{
   
  // Given N
  int N = 6;
 
  // Given []arr
  int []arr = { 1, 11, 4,
                27, 15, 33 };
 
  // Function Calling
  minCost(arr, N);
}
}
 
// This code is contributed by gauravrajput1


Javascript




<script>
 
// JavaScript program for above approach
 
// Function to find minimum cost
function minCost(arr, n)
{
    if (n == 1) {
        document.write( 0 );
        return;
    }
 
    // Sort the array
    arr.sort((a,b) => a-b);
 
    // Maximum possible common ratios
    var raised = 1 / (n - 1);
    var temp = Math.pow(arr[n - 1], raised);
    var r = Math.round(temp) + 1;
 
    var i, j, min_cost = 1000000000;
    var common_ratio = 1;
 
    // Iterate over all possible common ratios
    for (j = 1; j <= r; j++) {
        var curr_cost = 0, prod = 1;
 
        // Calculate operations required
        // for the current common ratio
        for (i = 0; i < n; i++) {
 
            curr_cost += Math.abs(arr[i] - prod);
            prod *= j;
            if (curr_cost >= min_cost)
                break;
        }
 
        // Calculate minimum cost
        if (i == n) {
            min_cost = Math.min(min_cost,
                           curr_cost);
            common_ratio = j;
        }
    }
 
    document.write( min_cost + ' ');
    document.write( common_ratio + ' ');
}
 
// Driver Code
 
// Given N
var N = 6;
 
// Given arr[]
var arr = [1, 11, 4, 27, 15, 33];
 
// Function Calling
minCost(arr, N);
 
</script>


Output

28 2







Time Complexity: O(N * K), where K is the maximum possible common ratio.
Auxiliary Space: O(1)

Using  Sorting:

Approach:

Another approach is to sort the given sequence in non-decreasing order and then try out all possible values of r on the sorted sequence. We can then calculate the cost of converting the sorted sequence to the expected sequence and return the minimum cost among all values of r.

Sort the given array in ascending order.
Find the maximum element in the sorted array.
For each possible value of r from 1 to the maximum element, calculate the expected geometric progression sequence for that value of r.
Calculate the cost of converting the given sequence into the expected geometric progression sequence for the current value of r.
Keep track of the minimum cost and the corresponding value of r that gives the minimum cost.
Return the minimum cost and the corresponding value of r.

C++




#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <climits> // Add this header for INT_MAX
 
using namespace std;
 
// Function to find the minimum cost and best 'r' value
// to minimize the absolute difference between array elements
// and corresponding expected values based on the power of 'r'
pair<int, int> min_operations(int N, vector<int>& arr) {
    // Sort the array in ascending order
    sort(arr.begin(), arr.end());
    int max_elem = arr[N - 1];
    int min_cost = INT_MAX; // Now INT_MAX is available
    int best_r = -1;
 
    // Iterate through all possible values of 'r'
    for (int r = 1; r <= max_elem; r++) {
        vector<int> expected;
        // Calculate the expected values based on the power of 'r'
        for (int i = 0; i < N; i++) {
            expected.push_back(pow(r, i));
        }
 
        // Compute the cost by taking the absolute difference
        // between array elements and corresponding expected values
        int cost = 0;
        for (int i = 0; i < N; i++) {
            cost += abs(arr[i] - expected[i]);
        }
 
        // Update the minimum cost and best 'r' value if the current 'r' results in a lower cost
        if (cost < min_cost) {
            min_cost = cost;
            best_r = r;
        }
    }
 
    // Return the pair containing the minimum cost and the best 'r'
    return make_pair(min_cost, best_r);
}
 
int main() {
    int N = 6;
    vector<int> arr = {1, 11, 4, 27, 15, 33};
 
    // Call the min_operations function and get the result
    auto result = min_operations(N, arr);
    int cost = result.first;
    int r = result.second;
 
    // Print the minimum cost and best 'r' value
    cout  << cost <<' ' << r << endl;
 
    // This code is contributed by Shivam Tiwari
    return 0;
}


Java




import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
 
class Pair<F, S> {
    private F first;
    private S second;
 
    public Pair(F first, S second) {
        this.first = first;
        this.second = second;
    }
 
    public F getFirst() {
        return first;
    }
 
    public S getSecond() {
        return second;
    }
}
 
public class Main {
    // Function to find the minimum cost and best 'r' value
    // to minimize the absolute difference between array elements
    // and corresponding expected values based on the power of 'r'
    public static Pair<Integer, Integer> minOperations(int N, List<Integer> arr) {
        // Sort the array in ascending order
        arr.sort(null);
        int maxElem = arr.get(N - 1);
        int minCost = Integer.MAX_VALUE;
        int bestR = -1;
 
        // Iterate through all possible values of 'r'
        for (int r = 1; r <= maxElem; r++) {
            List<Integer> expected = new ArrayList<>();
            // Calculate the expected values based on the power of 'r'
            for (int i = 0; i < N; i++) {
                expected.add((int) Math.pow(r, i));
            }
 
            // Compute the cost by taking the absolute difference
            // between array elements and corresponding expected values
            int cost = 0;
            for (int i = 0; i < N; i++) {
                cost += Math.abs(arr.get(i) - expected.get(i));
            }
 
            // Update the minimum cost and best 'r' value if the current 'r' results in a lower cost
            if (cost < minCost) {
                minCost = cost;
                bestR = r;
            }
        }
 
        // Return the pair containing the minimum cost and the best 'r'
        return new Pair<>(minCost, bestR);
    }
 
    public static void main(String[] args) {
        int N = 6;
        List<Integer> arr = Arrays.asList(1, 11, 4, 27, 15, 33);
 
        // Call the minOperations function and get the result
        Pair<Integer, Integer> result = minOperations(N, arr);
        int cost = result.getFirst();
        int r = result.getSecond();
 
        // Print the minimum cost and best 'r' value
        System.out.println(cost + " " + r);
 
        // This code is contributed by Shivam Tiwari
    }
}


Python3




def min_operations(N, arr):
    arr.sort()
    max_elem = arr[-1]
    min_cost = float('inf')
    best_r = -1
     
    for r in range(1, max_elem + 1):
        expected = [r**i for i in range(N)]
        cost = sum(abs(arr[i] - expected[i]) for i in range(N))
        if cost < min_cost:
            min_cost = cost
            best_r = r
     
    return min_cost, best_r
 
N = 6
arr = [1, 11, 4, 27, 15, 33]
cost, r = min_operations(N, arr)
print(cost, r)


C#




using System;
using System.Collections.Generic;
using System.Linq;
 
class Program
{
    // Function to find the minimum cost and best 'r' value
    // to minimize the absolute difference between array elements
    // and corresponding expected values based on the power of 'r'
    static Tuple<int, int> MinOperations(int N, List<int> arr)
    {
        // Sort the array in ascending order
        arr.Sort();
        int maxElem = arr[N - 1];
        int minCost = int.MaxValue; // Now int.MaxValue is available
        int bestR = -1;
 
        // Iterate through all possible values of 'r'
        for (int r = 1; r <= maxElem; r++)
        {
            List<int> expected = new List<int>();
            // Calculate the expected values based on the power of 'r'
            for (int i = 0; i < N; i++)
            {
                expected.Add((int)Math.Pow(r, i));
            }
 
            // Compute the cost by taking the absolute difference
            // between array elements and corresponding expected values
            int cost = 0;
            for (int i = 0; i < N; i++)
            {
                cost += Math.Abs(arr[i] - expected[i]);
            }
 
            // Update the minimum cost and best 'r' value if the current 'r' results in a lower cost
            if (cost < minCost)
            {
                minCost = cost;
                bestR = r;
            }
        }
 
        // Return the tuple containing the minimum cost and the best 'r'
        return Tuple.Create(minCost, bestR);
    }
 
    static void Main()
    {
        int N = 6;
        List<int> arr = new List<int> { 1, 11, 4, 27, 15, 33 };
 
        // Call the MinOperations function and get the result
        var result = MinOperations(N, arr);
        int cost = result.Item1;
        int r = result.Item2;
 
        // Print the minimum cost and best 'r' value
        Console.WriteLine($"{cost} {r}");
 
        // This code is contributed by Shivam Tiwari
    }
}


Javascript




// Function to find the minimum cost and best 'r' value
// to minimize the absolute difference between array elements
// and corresponding expected values based on the power of 'r'
function minOperations(N, arr) {
    // Sort the array in ascending order
    arr.sort((a, b) => a - b);
    const maxElem = arr[N - 1];
    let minCost = Infinity;
    let bestR = -1;
 
    // Iterate through all possible values of 'r'
    for (let r = 1; r <= maxElem; r++) {
        const expected = [];
        // Calculate the expected values based on the power of 'r'
        for (let i = 0; i < N; i++) {
            expected.push(Math.pow(r, i));
        }
 
        // Compute the cost by taking the absolute difference
        // between array elements and corresponding expected values
        let cost = 0;
        for (let i = 0; i < N; i++) {
            cost += Math.abs(arr[i] - expected[i]);
        }
 
        // Update the minimum cost and best 'r' value if the current 'r' results in a lower cost
        if (cost < minCost) {
            minCost = cost;
            bestR = r;
        }
    }
 
    // Return an object containing the minimum cost and the best 'r'
    return { minCost, bestR };
}
 
// Main function
function main() {
    const N = 6;
    const arr = [1, 11, 4, 27, 15, 33];
 
    // Call the minOperations function and get the result
    const result = minOperations(N, arr);
    const cost = result.minCost;
    const r = result.bestR;
 
    // Print the minimum cost and best 'r' value
    console.log(cost, r);
}
 
// Call the main function
main();


Output

28 2








Time Complexity: O(N^2 log(max_element))
Space Complexity: O(N)



Last Updated : 25 Nov, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads