Minimum number of operations to convert a given sequence into a Geometric Progression | Set 2
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++
#include <bits/stdc++.h>
using namespace std;
void minCost( int arr[], int n)
{
if (n == 1) {
cout << 0 << endl;
return ;
}
sort(arr, arr + n);
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;
for (j = 1; j <= r; j++) {
int curr_cost = 0, prod = 1;
for (i = 0; i < n; i++) {
curr_cost += abs (arr[i] - prod);
prod *= j;
if (curr_cost >= min_cost)
break ;
}
if (i == n) {
min_cost = min(min_cost,
curr_cost);
common_ratio = j;
}
}
cout << min_cost << ' ' ;
cout << common_ratio << ' ' ;
}
int main()
{
int N = 6;
int arr[] = { 1, 11, 4, 27, 15, 33 };
minCost(arr, N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static void minCost( int arr[],
int n)
{
if (n == 1 )
{
System.out.print( 0 + "\n" );
return ;
}
Arrays.sort(arr);
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 ;
for (j = 1 ; j <= r; j++)
{
int curr_cost = 0 , prod = 1 ;
for (i = 0 ; i < n; i++)
{
curr_cost += Math.abs(arr[i] -
prod);
prod *= j;
if (curr_cost >= min_cost)
break ;
}
if (i == n)
{
min_cost = Math.min(min_cost,
curr_cost);
common_ratio = j;
}
}
System.out.print(min_cost + " " );
System.out.print(common_ratio + " " );
}
public static void main(String[] args)
{
int N = 6 ;
int arr[] = { 1 , 11 , 4 ,
27 , 15 , 33 };
minCost(arr, N);
}
}
|
Python3
import sys
def minCost(arr, n):
if (n = = 1 ):
print ( 0 )
return
arr = sorted (arr)
raised = 1 / (n - 1 )
temp = pow (arr[n - 1 ], raised)
r = round (temp) + 1
min_cost = sys.maxsize
common_ratio = 1
for j in range ( 1 , r + 1 ):
curr_cost = 0
prod = 1
i = 0
while i < n:
curr_cost + = abs (arr[i] - prod)
prod * = j
if (curr_cost > = min_cost):
break
i + = 1
if (i = = n):
min_cost = min (min_cost,
curr_cost)
common_ratio = j
print (min_cost, common_ratio)
if __name__ = = '__main__' :
N = 6
arr = [ 1 , 11 , 4 , 27 , 15 , 33 ]
minCost(arr, N)
|
C#
using System;
class GFG{
static void minCost( int []arr,
int n)
{
if (n == 1)
{
Console.Write(0 + "\n" );
return ;
}
Array.Sort(arr);
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;
for (j = 1; j <= r; j++)
{
int curr_cost = 0, prod = 1;
for (i = 0; i < n; i++)
{
curr_cost += Math.Abs(arr[i] -
prod);
prod *= j;
if (curr_cost >= min_cost)
break ;
}
if (i == n)
{
min_cost = Math.Min(min_cost,
curr_cost);
common_ratio = j;
}
}
Console.Write(min_cost + " " );
Console.Write(common_ratio + " " );
}
public static void Main(String[] args)
{
int N = 6;
int []arr = { 1, 11, 4,
27, 15, 33 };
minCost(arr, N);
}
}
|
Javascript
<script>
function minCost(arr, n)
{
if (n == 1) {
document.write( 0 );
return ;
}
arr.sort((a,b) => a-b);
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;
for (j = 1; j <= r; j++) {
var curr_cost = 0, prod = 1;
for (i = 0; i < n; i++) {
curr_cost += Math.abs(arr[i] - prod);
prod *= j;
if (curr_cost >= min_cost)
break ;
}
if (i == n) {
min_cost = Math.min(min_cost,
curr_cost);
common_ratio = j;
}
}
document.write( min_cost + ' ' );
document.write( common_ratio + ' ' );
}
var N = 6;
var arr = [1, 11, 4, 27, 15, 33];
minCost(arr, N);
</script>
|
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;
pair< int , int > min_operations( int N, vector< int >& arr) {
sort(arr.begin(), arr.end());
int max_elem = arr[N - 1];
int min_cost = INT_MAX;
int best_r = -1;
for ( int r = 1; r <= max_elem; r++) {
vector< int > expected;
for ( int i = 0; i < N; i++) {
expected.push_back( pow (r, i));
}
int cost = 0;
for ( int i = 0; i < N; i++) {
cost += abs (arr[i] - expected[i]);
}
if (cost < min_cost) {
min_cost = cost;
best_r = r;
}
}
return make_pair(min_cost, best_r);
}
int main() {
int N = 6;
vector< int > arr = {1, 11, 4, 27, 15, 33};
auto result = min_operations(N, arr);
int cost = result.first;
int r = result.second;
cout << cost << ' ' << r << endl;
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 {
public static Pair<Integer, Integer> minOperations( int N, List<Integer> arr) {
arr.sort( null );
int maxElem = arr.get(N - 1 );
int minCost = Integer.MAX_VALUE;
int bestR = - 1 ;
for ( int r = 1 ; r <= maxElem; r++) {
List<Integer> expected = new ArrayList<>();
for ( int i = 0 ; i < N; i++) {
expected.add(( int ) Math.pow(r, i));
}
int cost = 0 ;
for ( int i = 0 ; i < N; i++) {
cost += Math.abs(arr.get(i) - expected.get(i));
}
if (cost < minCost) {
minCost = cost;
bestR = 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 );
Pair<Integer, Integer> result = minOperations(N, arr);
int cost = result.getFirst();
int r = result.getSecond();
System.out.println(cost + " " + r);
}
}
|
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
{
static Tuple< int , int > MinOperations( int N, List< int > arr)
{
arr.Sort();
int maxElem = arr[N - 1];
int minCost = int .MaxValue;
int bestR = -1;
for ( int r = 1; r <= maxElem; r++)
{
List< int > expected = new List< int >();
for ( int i = 0; i < N; i++)
{
expected.Add(( int )Math.Pow(r, i));
}
int cost = 0;
for ( int i = 0; i < N; i++)
{
cost += Math.Abs(arr[i] - expected[i]);
}
if (cost < minCost)
{
minCost = cost;
bestR = r;
}
}
return Tuple.Create(minCost, bestR);
}
static void Main()
{
int N = 6;
List< int > arr = new List< int > { 1, 11, 4, 27, 15, 33 };
var result = MinOperations(N, arr);
int cost = result.Item1;
int r = result.Item2;
Console.WriteLine($ "{cost} {r}" );
}
}
|
Javascript
function minOperations(N, arr) {
arr.sort((a, b) => a - b);
const maxElem = arr[N - 1];
let minCost = Infinity;
let bestR = -1;
for (let r = 1; r <= maxElem; r++) {
const expected = [];
for (let i = 0; i < N; i++) {
expected.push(Math.pow(r, i));
}
let cost = 0;
for (let i = 0; i < N; i++) {
cost += Math.abs(arr[i] - expected[i]);
}
if (cost < minCost) {
minCost = cost;
bestR = r;
}
}
return { minCost, bestR };
}
function main() {
const N = 6;
const arr = [1, 11, 4, 27, 15, 33];
const result = minOperations(N, arr);
const cost = result.minCost;
const r = result.bestR;
console.log(cost, r);
}
main();
|
Time Complexity: O(N^2 log(max_element))
Space Complexity: O(N)
Last Updated :
25 Nov, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...