📜  从一个块构建N个块的最低成本

📅  最后修改于: 2021-04-22 03:41:55             🧑  作者: Mango

给定数字N,任务是通过执行以下操作从1个块构建N个块:

  1. 容器中存在的块数加倍,此操作的成本为X
  2. 将容器中存在的块数增加1,此操作的成本为Y
  3. 将容器中存在的块数减少一个,此操作的成本为Z

例子:

方法:

  • f(i)表示构建i块的最低成本。所以f(i) = min(f(2*i)+X, f(i-1)+Y, f(i+1)+Z)
    此处,当前值取决于其下一个值以及其前一个值,但是您知道在动态编程中,当前值仅取决于其前一个值。因此,尝试将其下一个值转换为其先前的值。我们可以将f(2*i)写为f(i/2)因为当我们已经构建了i / 2个块时,我们可以将当前块的数量加倍或将块的数量加1或将块的数量减1。在这里,无需计算f(2*i)
    现在
    f(i) = min(f(i/2)+X, f(i-1)+Y, f(i+1)+Z)
  • 如果i是偶数,那么(i+1)必须是奇数。我们只能通过执行增量操作和双精度操作来构建(i)块,所以您为什么不需要执行减量操作?
    这是因为(i+1)是奇数,因此如果您通过执行增量运算来构建(i+1)块,则可以确认我们已经构建了i块,这意味着我们拥有构建i块的成本最低。我们执行任何其他操作都必须增加与您无关的最佳成本。所以当我什至是递归关系时:
    f(i)=min(f(i/2)+X, f(i-1)+Y)
  • 如果i为奇数,则(i+1)必须为偶数。我们只能通过执行两次或递减运算来构建(i+1)块,为什么不执行递增运算呢?
    这是因为如果您已经构建了i块,则无需构建(i+1)块,因为这会增加成本。因此我们可以计算出f(i+1)=f((i+1)/2)+ X.所以当i为奇数时,递归关系为:
    f(i)=min(f(i-1)+Y, f( (i+1)/2)+X+Z)

    下面是上述方法的实现:

    CPP
    // C++ program to Minimum cost
    // to build N blocks from one block
      
    #include 
    using namespace std;
      
    // Function to calculate
    // min cost to build N blocks
    int minCost(int n, int x, int y, int z)
    {
        int dp[n + 1] = { 0 };
      
        // Initialize base case
        dp[0] = dp[1] = 0;
      
        for (int i = 2; i <= n; i++) {
            // Recurence when
            // i is odd
            if (i % 2 == 1) {
                dp[i] = min(
                    dp[(i + 1) / 2] + x + z,
                    dp[i - 1] + y);
            }
            // Recurence when
            // i is even
            else {
                dp[i] = min(dp[i / 2] + x,
                            dp[i - 1] + y);
            }
        }
      
        return dp[n];
    }
      
    // Driver code
    int main()
    {
        int n = 5, x = 2, y = 1, z = 3;
        cout << minCost(n, x, y, z) << endl;
      
        return 0;
    }


    Java
    // Java program to Minimum cost
    // to build N blocks from one block
    class GFG
    {
      
    // Function to calculate
    // min cost to build N blocks
    static int minCost(int n, int x, int y, int z)
    {
        int dp[] = new int[n + 1];
      
        // Initialize base case
        dp[0] = dp[1] = 0;
      
        for (int i = 2; i <= n; i++)
        {
            // Recurence when
            // i is odd
            if (i % 2 == 1)
            {
                dp[i] = Math.min(
                    dp[(i + 1) / 2] + x + z,
                    dp[i - 1] + y);
            }
            // Recurence when
            // i is even
            else 
            {
                dp[i] = Math.min(dp[i / 2] + x,
                            dp[i - 1] + y);
            }
        }
      
        return dp[n];
    }
      
    // Driver code
    public static void main(String[] args)
    {
        int n = 5, x = 2, y = 1, z = 3;
        System.out.print(minCost(n, x, y, z) +"\n");
      
    }
    }
      
    // This code is contributed by Rajput-Ji


    Python
    # python3 program to Minimum cost
    # to build N blocks from one block
      
    # Function to calculate
    # min cost to build N blocks
    def minCost(n, x, y, z):
        dp = [0] * (n + 1)
      
        # Initialize base case
        dp[0] = dp[1] = 0
      
        for i in range(2, n + 1):
              
            # Recurence when
            # i is odd
            if (i % 2 == 1):
                dp[i] = min(dp[(i + 1) // 2] + x + z, dp[i - 1] + y)
              
            # Recurence when
            # i is even
            else:
                dp[i] = min(dp[i // 2] + x, dp[i - 1] + y)
      
        return dp[n]
      
    # Driver code
    n = 5
    x = 2
    y = 1
    z = 3
    print(minCost(n, x, y, z))
      
    # This code is contributed by mohit kumar 29


    C#
    // C# program to Minimum cost
    // to build N blocks from one block
    using System;
      
    class GFG
    {
      
    // Function to calculate
    // min cost to build N blocks
    static int minCost(int n, int x, int y, int z)
    {
        int []dp = new int[n + 1];
      
        // Initialize base case
        dp[0] = dp[1] = 0;
      
        for (int i = 2; i <= n; i++)
        {
            // Recurence when
            // i is odd
            if (i % 2 == 1)
            {
                dp[i] = Math.Min(
                    dp[(i + 1) / 2] + x + z,
                    dp[i - 1] + y);
            }
              
            // Recurence when
            // i is even
            else
            {
                dp[i] = Math.Min(dp[i / 2] + x,
                            dp[i - 1] + y);
            }
        }
        return dp[n];
    }
      
    // Driver code
    public static void Main(String[] args)
    {
        int n = 5, x = 2, y = 1, z = 3;
        Console.Write(minCost(n, x, y, z) +"\n");
    }
    }
      
    // This code is contributed by PrinciRaj1992


    输出:
    4