Open In App

Minimum cost to convert a ‘1’ to a given number

Given a positive integer ‘n’. Starting with 1 find the minimum cost required to convert it to n using the following operations :

Examples:



Input: n = 31, a = 2, b = 5, c = 3
Output: 13
Explanation: The minimum cost transition to convert 1 to 31 is shown below:

  • 1 -> 2 -> 4 -> 8 -> 16 -> 32 -> 31.
  • Total cost = a+a+a+a+a+c = 2+2+2+2+2+3 = 13

Input: n = 31, a = 2, b = 1, c = 3
Output: 11
Explanation: The minimum cost transition to convert 1 to 31 is shown below:



  • 1 -> 2 -> 3 -> 6 -> 7 -> 14 -> 15 -> 30 -> 31.
  • Total cost = b+b+a+b+a+b+a+b = 1+1+2+1+2+1+2+1 = 11

Approach: To solve the problem follow the below idea:

The problem can be solved by exploring different paths to reach the target number while keeping track of the costs. This can be done using data structures such as priority queues. It starts with the number 1 and systematically applies three operations: Doubling the number, adding 1, and subtracting 1. These operations generate new numbers. The priority queue ensures that paths with lower costs are explored first, helping to find the minimum cost to reach the target number ‘n’. This approach is like searching the “cheapest” path through a number space to reach the desired value.

Let’s break down the approach and the code:

Below is the implementation of the above approach:




// C++ code to convert 1 to n in minimum cost
// possible using given operations
#include <bits/stdc++.h>
using namespace std;
class X {
public:
   
    // Comparator for the priority queue to make
    // sure pairs with lower costs come first.
    bool operator()(pair<int, int>& a, pair<int, int>& b)
    {
        return a.second > b.second;
    }
};
 
int min_cost(int n, int a, int b, int c)
{
    int ans;
    vector<int> vis(2 * n);
 
    priority_queue<pair<int, int>, vector<pair<int, int> >,
                   X>
        pq;
 
    pq.push({ 1, 0 });
 
    while (!pq.empty()) {
 
        // pop the top pair from pq
        auto f = pq.top();
 
        pq.pop();
        if (f.first == n) {
 
            // if the destination number is
            // reached break out of the loop
            ans = f.second;
            break;
        }
 
        // if already visited continue
        if (vis[f.first] == 1)
            continue;
 
        vis[f.first] = 1;
 
        if (2 * f.first < 2 * n && vis[f.first * 2] == 0) {
            pq.push({ f.first * 2, f.second + a });
        }
        if (f.first + 1 < 2 * n && vis[f.first + 1] == 0) {
            pq.push({ f.first + 1, f.second + b });
        }
        if (f.first - 1 > 1 && vis[f.first - 1] == 0) {
            pq.push({ f.first - 1, f.second + c });
        }
    }
 
    return ans;
}
 
// Drivers code
signed main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
 
    // Denotes number 'n'
    int n = 31;
 
    // Denotes cost 'a'
    int a = 2;
 
    // Denotes cost 'b'
    int b = 1;
 
    // Denotes cost 'c'
    int c = 3;
 
    // Function call
    cout << min_cost(n, a, b, c) << "\n";
 
    return 0;
}




// Java code to convert 1 to n in minimum cost possible using given operations
import java.util.*;
 
class Pair {
    public int first, second;
 
    Pair(int first, int second)
    {
        this.first = first;
        this.second = second;
    }
}
 
class X implements Comparator<Pair> {
      // comparator for the priority queue to make sure pairs with lower costs come first.
    public int compare(Pair a, Pair b)
    {
        return a.second - b.second;
    }
}
 
public class GFG {
 
    static int minCost(int n, int a, int b, int c)
    {
        int ans = 0;
        boolean[] vis = new boolean[2 * n];
 
        PriorityQueue<Pair> pq
            = new PriorityQueue<>(new X());
        pq.add(new Pair(1, 0));
 
        while (!pq.isEmpty()) {
            Pair f = pq.poll();             // pop the top pair from pq
            if (f.first == n) {
                ans = f.second;             // if the destination number is reached break out of the loop
                break;
            }
            if (vis[f.first] == true)       // if already visited continue
                continue;
 
            vis[f.first] = true;
 
            if (2 * f.first < 2 * n
                && vis[2 * f.first] == false) {
                pq.add(new Pair(2 * f.first, f.second + a));
            }
            if (f.first + 1 < 2 * n
                && vis[f.first + 1] == false) {
                pq.add(new Pair(f.first + 1, f.second + b));
            }
            if (f.first - 1 > 1
                && vis[f.first - 1] == false) {
                pq.add(new Pair(f.first - 1, f.second + c));
            }
        }
 
        return ans;
    }
 
    public static void main(String[] args)
    {
        int n = 31;
        int a = 2;
        int b = 1;
        int c = 3;
 
        System.out.println(minCost(n, a, b, c));
    }
}
// This code is contribured by Shikhar Reyya




# python code to convert 1 to n in minimum cost possible using given operations
import heapq
 
def min_cost(n, a, b, c):
    ans = 0
    vis = [0] * (2 * n)
 
    pq = []
    heapq.heappush(pq, (0, 1))  # Inverted order for the cost and value
 
    while pq:
        cost, f = heapq.heappop(pq)
        if f == n:
            ans = cost
            break
        if vis[f] == 1:
            continue
         
        vis[f] = 1
 
        if 2 * f < 2 * n and vis[2 * f] == 0:
            heapq.heappush(pq, (cost + a, 2 * f))
        if f + 1 < 2 * n and vis[f + 1] == 0:
            heapq.heappush(pq, (cost + b, f + 1))
        if f - 1 > 1 and vis[f - 1] == 0:
            heapq.heappush(pq, (cost + c, f - 1))
 
    return ans
 
n = 31
a = 2
b = 1
c = 3
print(min_cost(n, a, b, c))
# This code is contribured by Shikhar Reyya




// C# code to convert 1 to n in minimum cost possible using given operations
using System;
using System.Collections.Generic;
 
class X : IComparer<Pair> {
      // comparator for the priority queue to make sure pairs with lower costs come first.
    public int Compare(Pair a, Pair b) {
        return a.Second.CompareTo(b.Second);
    }
}
 
class Pair {
    public int First { get; set; }
    public int Second { get; set; }
 
    public Pair(int first, int second) {
        First = first;
        Second = second;
    }
}
 
class GFG {
    static int MinCost(int n, int a, int b, int c) {
        int ans = 0;
 
        bool[] vis = new bool[2 * n];
 
        PriorityQueue<Pair> pq = new PriorityQueue<Pair>(new X());
        pq.Enqueue(new Pair(1, 0));
 
        while (pq.Count > 0) {
            Pair f = pq.Dequeue();                // pop the top pair from pq
            if (f.First == n) {
                ans = f.Second;           // if the destination number is reached break out of the loop
                break;
            }
            if (vis[f.First] == true) continue;        // if already visited continue
 
            vis[f.First] = true;
 
            if (2 * f.First < 2 * n && vis[2 * f.First] == false) {
                pq.Enqueue(new Pair(2 * f.First, f.Second + a));
            }
            if (f.First + 1 < 2 * n && vis[f.First + 1] == false) {
                pq.Enqueue(new Pair(f.First + 1, f.Second + b));
            }
            if (f.First - 1 > 1 && vis[f.First - 1] == false) {
                pq.Enqueue(new Pair(f.First - 1, f.Second + c));
            }
        }
 
        return ans;
    }
 
    public static void Main(string[] args) {
        int n = 31;
        int a = 2;
        int b = 1;
        int c = 3;
 
        Console.WriteLine(MinCost(n, a, b, c));
    }
 
    public class PriorityQueue<T> {
        private List<T> data;
        private IComparer<T> comparer;
 
        public PriorityQueue(IComparer<T> comparer) {
            this.data = new List<T>();
            this.comparer = comparer;
        }
 
        public void Enqueue(T item) {
            data.Add(item);
            int ci = data.Count - 1;
            while (ci > 0) {
                int pi = (ci - 1) / 2;
                if (comparer.Compare(data[ci], data[pi]) >= 0)
                    break;
                T tmp = data[ci]; data[ci] = data[pi]; data[pi] = tmp;
                ci = pi;
            }
        }
 
        public T Dequeue() {
            int li = data.Count - 1;
            T frontItem = data[0];
            data[0] = data[li];
            data.RemoveAt(li);
 
            --li;
            int pi = 0;
            while (true) {
                int ci = pi * 2 + 1;
                if (ci > li) break;
                int rc = ci + 1;
                if (rc <= li && comparer.Compare(data[rc], data[ci]) < 0)
                    ci = rc;
                if (comparer.Compare(data[pi], data[ci]) <= 0) break;
                T tmp = data[pi]; data[pi] = data[ci]; data[ci] = tmp;
                pi = ci;
            }
            return frontItem;
        }
 
        public T Peek() {
            T frontItem = data[0];
            return frontItem;
        }
 
        public int Count => data.Count;
    }
}
// This code is contribured by Shikhar Reyya




// Javascript code for the above approach:
 
class Pair {
    constructor(first, second) {
        this.first = first;
        this.second = second;
    }
}
 
class PriorityQueue {
    constructor() {
        this.queue = [];
    }
 
    // Comparator for the priority queue to make sure pairs with lower costs come first.
    add(pair) {
        this.queue.push(pair);
        this.queue.sort((a, b) => a.second - b.second);
    }
 
    poll() {
        if (this.isEmpty()) {
            return null;
        }
        return this.queue.shift();
    }
 
    isEmpty() {
        return this.queue.length === 0;
    }
}
 
function minCost(n, a, b, c) {
    let ans = 0;
    const vis = new Array(2 * n).fill(false);
 
    const pq = new PriorityQueue();
    pq.add(new Pair(1, 0));
 
    while (!pq.isEmpty()) {
        const f = pq.poll();
        if (f.first === n) {
            ans = f.second;
            break;
        }
        if (vis[f.first]) {
            continue;
        }
 
        vis[f.first] = true;
 
        if (2 * f.first < 2 * n && !vis[2 * f.first]) {
            pq.add(new Pair(2 * f.first, f.second + a));
        }
        if (f.first + 1 < 2 * n && !vis[f.first + 1]) {
            pq.add(new Pair(f.first + 1, f.second + b));
        }
        if (f.first - 1 > 1 && !vis[f.first - 1]) {
            pq.add(new Pair(f.first - 1, f.second + c));
        }
    }
 
    return ans;
}
 
const n = 31;
const a = 2;
const b = 1;
const c = 3;
 
console.log(minCost(n, a, b, c));

Output
11




Time Complexity: O(n * log(n))
Auxiliary Space: O(n)


Article Tags :