📜  使用动态编程以给定的操作将N转换为M

📅  最后修改于: 2021-05-05 02:05:13             🧑  作者: Mango

给定两个整数NM ,任务是通过以下操作将N转换为M

  1. N乘以2,N = N * 2
  2. N中减去1 ,即N = N – 1

例子:

方法:创建大小为MAX = 10 5 + 5的数组dp []以存储答案,以防止一次又一次地进行相同的计算,并使用-1初始化所有数组元素。

  • 如果N≤0N≥MAX表示无法将其转换为M ,则返回MAX
  • 如果N = M,则返回0,因为N已转换为M。
  • 否则,如果dp [N]上的值不是-1 ,则表示它已被较早地计算出来,因此返回dp [N]
  • 如果为-1,则将调用递归函数2 * NN – 1并返回最小值,因为如果N为奇数,则只能通过执行N – 1次运算才能达到,如果N为偶数则2 * N必须执行清除操作,因此请同时检查两个可能性并返回最小值。

下面是上述方法的实现:

C++
// C++ implementation of the approach
#include 
using namespace std;
  
const int N = 1e5 + 5;
  
int n, m;
int dp[N];
  
// Function to reutrn the minimum
// number of given operations
// required to convert n to m
int minOperations(int k)
{
    // If k is either 0 or out of range
    // then return max
    if (k <= 0 || k >= 2e4) {
        return 1e9;
    }
  
    // If k = m then conversion is
    // complete so return 0
    if (k == m) {
        return 0;
    }
  
    int& ans = dp[k];
  
    // If it has been calculated earlier
    if (ans != -1) {
        return ans;
    }
    ans = 1e9;
  
    // Call for 2*k and k-1 and return
    // the minimum of them. If k is even
    // then it can be reached by 2*k opertaions
    // and If k is odd then it can be reached
    // by k-1 opertaions so try both cases
    // and return the minimum of them
    ans = 1 + min(minOperations(2 * k),
                  minOperations(k - 1));
    return ans;
}
  
// Driver code
int main()
{
    n = 4, m = 6;
    memset(dp, -1, sizeof(dp));
  
    cout << minOperations(n);
  
    return 0;
}


Java
// Java implementation of the approach 
import java.util.*;
  
class GFG
{
    static final int N = 10000;
    static int n, m;
    static int[] dp = new int[N];
  
    // Function to reutrn the minimum
    // number of given operations
    // required to convert n to m
    static int minOperations(int k) 
    {
  
        // If k is either 0 or out of range
        // then return max
        if (k <= 0 || k >= 10000)
            return 1000000000;
  
        // If k = m then conversion is
        // complete so return 0
        if (k == m)
            return 0;
  
        dp[k] = dp[k];
  
        // If it has been calculated earlier
        if (dp[k] != -1)
            return dp[k];
        dp[k] = 1000000000;
  
        // Call for 2*k and k-1 and return
        // the minimum of them. If k is even
        // then it can be reached by 2*k opertaions
        // and If k is odd then it can be reached
        // by k-1 opertaions so try both cases
        // and return the minimum of them
        dp[k] = 1 + Math.min(minOperations(2 * k), 
                             minOperations(k - 1));
        return dp[k];
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        n = 4;
        m = 6;
        Arrays.fill(dp, -1);
        System.out.println(minOperations(n));
    }
}
  
// This code is contributed by
// sanjeev2552


Python3
# Python3 implementation of the approach
N = 1000
dp = [-1] * N
  
# Function to reutrn the minimum
# number of given operations
# required to convert n to m
def minOperations(k):
  
    # If k is either 0 or out of range
    # then return max
    if (k <= 0 or k >= 1000): 
        return 1e9
      
    # If k = m then conversion is
    # complete so return 0
    if (k == m): 
        return 0
      
    dp[k] = dp[k]
      
    # If it has been calculated earlier
    if (dp[k] != -1): 
        return dp[k]
      
    dp[k] = 1e9
      
    # Call for 2*k and k-1 and return
    # the minimum of them. If k is even
    # then it can be reached by 2*k opertaions
    # and If k is odd then it can be reached
    # by k-1 opertaions so try both cases
    # and return the minimum of them
    dp[k] = 1 + min(minOperations(2 * k),
                    minOperations(k - 1))
    return dp[k]
  
# Driver code
if __name__ == '__main__':
    n = 4
    m = 6
    print(minOperations(n)) 
      
# This code is contributed by ashutosh450


C#
// C# implementation of the approach 
using System;
using System.Linq;
  
class GFG
{
    static int N = 10000;
    static int n, m;
    static int[] dp = Enumerable.Repeat(-1, N).ToArray();
  
    // Function to reutrn the minimum
    // number of given operations
    // required to convert n to m
    static int minOperations(int k) 
    {
  
        // If k is either 0 or out of range
        // then return max
        if (k <= 0 || k >= 10000)
            return 1000000000;
  
        // If k = m then conversion is
        // complete so return 0
        if (k == m)
            return 0;
  
        dp[k] = dp[k];
  
        // If it has been calculated earlier
        if (dp[k] != -1)
            return dp[k];
        dp[k] = 1000000000;
  
        // Call for 2*k and k-1 and return
        // the minimum of them. If k is even
        // then it can be reached by 2*k opertaions
        // and If k is odd then it can be reached
        // by k-1 opertaions so try both cases
        // and return the minimum of them
        dp[k] = 1 + Math.Min(minOperations(2 * k), 
                             minOperations(k - 1));
        return dp[k];
    }
  
    // Driver Code
    public static void Main(String[] args)
    {
        n = 4;
        m = 6;
          
        //Arrays.fill(dp, -1);
        Console.Write(minOperations(n));
    }
}
  
// This code is contributed by
// Mohit kumar 29


输出:
2