📜  基于成本的河内塔

📅  最后修改于: 2021-09-16 11:00:26             🧑  作者: Mango

这里解释了标准的河内塔问题。在标准问题中,所有磁盘事务都被认为是相同的。给定一个 3×3 矩阵 cost[][] 包含在杆之间转移盘的成本,其中cost[i][j]存储将盘从杆 i转移到杆 j的成本。同一杆之间的转移成本为0 .因此成本矩阵的对角线元素都是0 。任务是打印所有N 个圆盘从杆 1转移到杆 3的最小成本。
例子:

方法:想法是使用自顶向下的动态编程。
假设mincost(idx, src, dest)是将索引idxN的磁盘从rod src转移到rod dest的最小成本。第三根杆既不是源杆也不是目标杆,其值rem = 6 – (i + j),因为杆数是 1、2 和 3,它们的总和是 6。如果第 1 和第 3 根杆是源和分别到达目的地,则辅助杆的编号为 6 – (1 + 3) = 2。
现在将问题分解为子问题如下:

  • 案例1:首先将所有索引为(idx + 1)到N的圆盘转移到剩余的杆上。现在将最大的圆盘转移到目标杆。再次将所有圆盘从剩余杆转移到目标杆。这个过程将花费为。
  • 情况二:首先将所有索引为(idx+1)为N的圆盘转移到目标棒上。现在将最大的圆盘转移到剩余的杆上。再次将所有光盘从目标杆转移到源杆。现在将最大的圆盘从剩余的杆转移到目标杆。再次将光盘从源棒转移到目标棒。这个过程将花费为:
  • 答案将等于上述两种情况中的最小值。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
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 auxiliary 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;
}


Java
// 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 auxiliary 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@


Python3
# 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 auxiliary 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


C#
// 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 auxiliary 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 */


Javascript


输出:
12

时间复杂度: O(N),其中 N 是给定棒中的圆盘数。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程