Cost Based Tower of Hanoi

The standard Tower of Hanoi problem is explained here . In the standard problem, all the disc transactions are considered identical. Given a 3×3 matrix costs[][] containing the costs of transfer of disc between the rods where costs[i][j] stores the cost of transferring a disc from rod i to rod j. Cost of transfer between the same rod is 0. Hence the diagonal elements of the cost matrix are all 0s. The task is to print the minimum cost in which all the N discs are transferred from rod 1 to rod 3.

Examples:

Input: N = 2
costs = {
{ 0, 1, 2},
{ 2, 0, 1},
{ 3, 2, 0}}
Output: 4
There are 2 discs, the smaller one is on the bigger one.
Transfer the smaller disc from rod 1 to rod 2.
Cost of this transfer is equal to 1
Transfer the bigger disc to from rod 1 to rod 3.
Cost of this transfer is equal to 2.
Transfer the smaller disc to from rod 2 to rod 3.
Cost of this transfer is equal to 1
Total minimum cost is equal to 4.



Input: N = 3
costs = {
{ 0, 1, 2},
{ 2, 0, 1},
{ 3, 2, 0}}
Output: 12

Approach: Idea is to use Top-down Dynamic programming.
Let’s say mincost(idx, src, dest) be the minimum cost for transferring the discs of indices idx to N from rod src to rod dest. The third rod which is neither the source nor the destination rod would have the value rem = 6 – (i + j) as the rod numbers are 1, 2 and 3 and their sum is 6. If 1st and 3rd rods are the source and destination respectively then the auxilary rod will have number as 6 – (1 + 3) = 2.
Now break the problem into its subproblems as follows:

  • Case 1: First transfer all the discs with index (idx + 1) to N to the remaining rod. Now transfer the largest disc to destination rod. Again transfer all the discs from remaining rod to the destination rod. This process would cost as.

    Cost = mincost(idx + 1, src, rem) + costs[src][dest] + mincost(idx + 1, rem, dest)

  • Case 2: First transfer all the discs with index (idx + 1) to N to the destination rod. Now transfer the largest disc to remaining rod. Again transfer all the discs from destination rod to the source rod. Now transfer the largest disc from remaining rod to the destination rod. Again transfer the discs from source rod to destination rod. This process would cost as:

    Cost = mincost(idx + 1, src, dest) + costs[src][rem] + mincost(idx + 1, dest, src) + cost[rem][dest] + mincost(idx + 1, src, dest)

  • Answer would be equal to the minimum of the above two cases.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
#define RODS 3
#define N 3
int dp[N + 1][RODS + 1][RODS + 1];
  
// Function to initialize the dp table
void initialize()
{
  
    // Initialize with maximum value
    for (int i = 0; i <= N; i += 1) {
        for (int j = 1; j <= RODS; j++) {
            for (int k = 1; k <= RODS; k += 1) {
                dp[i][j][k] = INT_MAX;
            }
        }
    }
}
// Function to return the minimum cost
int mincost(int idx, int src, int dest,
            int costs[RODS][RODS])
{
  
    // Base case
    if (idx > N)
        return 0;
  
    // If problem is already solved,
    // return the pre-calculated answer
    if (dp[idx][src][dest] != INT_MAX)
        return dp[idx][src][dest];
  
    // Number of the auxilary disk
    int rem = 6 - (src + dest);
  
    // Initialize the minimum cost as Infinity
    int ans = INT_MAX;
  
    // Calculationg the cost for first case
    int case1 = costs[src - 1][dest - 1]
                + mincost(idx + 1, src, rem, costs)
                + mincost(idx + 1, rem, dest, costs);
  
    // Calculating the cost for second case
    int case2 = costs[src - 1][rem - 1]
                + mincost(idx + 1, src, dest, costs)
                + mincost(idx + 1, dest, src, costs)
                + costs[rem - 1][dest - 1]
                + mincost(idx + 1, src, dest, costs);
  
    // Minimum of both the above cases
    ans = min(case1, case2);
  
    // Store it in the dp table
    dp[idx][src][dest] = ans;
  
    // Return the minimum cost
    return ans;
}
  
// Driver code
int main()
{
    int costs[RODS][RODS] = { { 0, 1, 2 },
                              { 2, 0, 1 },
                              { 3, 2, 0 } };
    initialize();
    cout << mincost(1, 1, 3, costs);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.io.*;
  
class GFG
{
      
static int RODS = 3;
static int N = 3;
static int [][][]dp=new int[N + 1][RODS + 1][RODS + 1];
  
// Function to initialize the dp table
static void initialize()
{
  
    // Initialize with maximum value
    for (int i = 0; i <= N; i += 1)
    {
        for (int j = 1; j <= RODS; j++)
        {
            for (int k = 1; k <= RODS; k += 1
            {
                dp[i][j][k] = Integer.MAX_VALUE;
            }
        }
    }
}
  
// Function to return the minimum cost
static int mincost(int idx, int src, int dest,int costs[][])
{
  
    // Base case
    if (idx > N)
        return 0;
  
    // If problem is already solved,
    // return the pre-calculated answer
    if (dp[idx][src][dest] != Integer.MAX_VALUE)
        return dp[idx][src][dest];
  
    // Number of the auxilary disk
    int rem = 6 - (src + dest);
  
    // Initialize the minimum cost as Infinity
    int ans = Integer.MAX_VALUE;
  
    // Calculationg the cost for first case
    int case1 = costs[src - 1][dest - 1]
                + mincost(idx + 1, src, rem, costs)
                + mincost(idx + 1, rem, dest, costs);
  
    // Calculating the cost for second case
    int case2 = costs[src - 1][rem - 1]
                + mincost(idx + 1, src, dest, costs)
                + mincost(idx + 1, dest, src, costs)
                + costs[rem - 1][dest - 1]
                + mincost(idx + 1, src, dest, costs);
  
    // Minimum of both the above cases
    ans = Math.min(case1, case2);
  
    // Store it in the dp table
    dp[idx][src][dest] = ans;
  
    // Return the minimum cost
    return ans;
}
  
// Driver code
public static void main (String[] args) 
{
          
    int [][]costs = { { 0, 1, 2 },
                            { 2, 0, 1 },
                            { 3, 2, 0 } };
    initialize();
        System.out.print (mincost(1, 1, 3, costs));
          
}
}
  
// This code is contributed by ajit..23@ 

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach 
import numpy as np
import sys
  
RODS = 3 
N = 3 
dp = np.zeros((N + 1,RODS + 1,RODS + 1)); 
  
# Function to initialize the dp table 
def initialize() :
  
    # Initialize with maximum value 
    for i in range(N + 1) :
        for j in range(1, RODS + 1) :
            for k in range(1, RODS + 1) :
                dp[i][j][k] = sys.maxsize; 
              
  
# Function to return the minimum cost 
def mincost(idx, src, dest, costs) :
  
    # Base case 
    if (idx > N) :
        return 0
  
    # If problem is already solved, 
    # return the pre-calculated answer 
    if (dp[idx][src][dest] != sys.maxsize) :
        return dp[idx][src][dest]; 
  
    # Number of the auxilary disk 
    rem = 6 - (src + dest); 
  
    # Initialize the minimum cost as Infinity 
    ans = sys.maxsize; 
  
    # Calculationg the cost for first case 
    case1 = costs[src - 1][dest - 1] + mincost(idx + 1, src, rem, costs) + mincost(idx + 1, rem, dest, costs); 
  
    # Calculating the cost for second case 
    case2 = (costs[src - 1][rem - 1] + mincost(idx + 1, src, dest, costs) + mincost(idx + 1, dest, src, costs) + costs[rem - 1][dest - 1] + mincost(idx + 1, src, dest, costs)); 
  
    # Minimum of both the above cases 
    ans = min(case1, case2); 
  
    # Store it in the dp table 
    dp[idx][src][dest] = ans; 
  
    # Return the minimum cost 
    return ans; 
  
  
# Driver code 
if __name__ == "__main__"
  
    costs = [ [ 0, 1, 2 ], 
            [ 2, 0, 1 ], 
            [ 3, 2, 0 ] ]; 
    initialize(); 
    print(mincost(1, 1, 3, costs)); 
  
    # This code is contributed by AnkitRai01

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System; 
      
class GFG
{
      
static int RODS = 3;
static int N = 3;
static int [,,]dp=new int[N + 1,RODS + 1,RODS + 1];
  
// Function to initialize the dp table
static void initialize()
{
  
    // Initialize with maximum value
    for (int i = 0; i <= N; i += 1)
    {
        for (int j = 1; j <= RODS; j++)
        {
            for (int k = 1; k <= RODS; k += 1) 
            {
                dp[i,j,k] = int.MaxValue;
            }
        }
    }
}
  
// Function to return the minimum cost
static int mincost(int idx, int src, int dest,int [,]costs)
{
  
    // Base case
    if (idx > N)
        return 0;
  
    // If problem is already solved,
    // return the pre-calculated answer
    if (dp[idx,src,dest] != int.MaxValue)
        return dp[idx,src,dest];
  
    // Number of the auxilary disk
    int rem = 6 - (src + dest);
  
    // Initialize the minimum cost as Infinity
    int ans = int.MaxValue;
  
    // Calculationg the cost for first case
    int case1 = costs[src - 1,dest - 1]
                + mincost(idx + 1, src, rem, costs)
                + mincost(idx + 1, rem, dest, costs);
  
    // Calculating the cost for second case
    int case2 = costs[src - 1,rem - 1]
                + mincost(idx + 1, src, dest, costs)
                + mincost(idx + 1, dest, src, costs)
                + costs[rem - 1,dest - 1]
                + mincost(idx + 1, src, dest, costs);
  
    // Minimum of both the above cases
    ans = Math.Min(case1, case2);
  
    // Store it in the dp table
    dp[idx,src,dest] = ans;
  
    // Return the minimum cost
    return ans;
}
  
// Driver code
public static void Main (String[] args) 
{
          
    int [,]costs = { { 0, 1, 2 },
                            { 2, 0, 1 },
                            { 3, 2, 0 } };
    initialize();
        Console.WriteLine(mincost(1, 1, 3, costs));
          
}
}
  
/* This code is contributed by PrinciRaj1992 */

chevron_right


Output:

12

Time Complexity: O(N) where N is the number of discs in given rod.



My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.