📌  相关文章
📜  通过给定操作从1中获得N的最小步骤

📅  最后修改于: 2021-04-26 06:13:46             🧑  作者: Mango

给定整数N ,任务是找到从1开始获得数N所需的最小操作数。以下是操作:

  • 在当前数字上加1。
  • 将当前数字乘以2。
  • 将当前数字乘以3。

打印所需的最少操作数以及获得N的相应顺序。

例子:

递归方法:递归地生成每种可能的组合,以将N减少到1并计算所需的操作数。最后,在用尽所有可能的组合之后,打印需要最少操作数的顺序。

下面是上述方法的实现:

C++
// C++ program to implement
// the above approach
#include 
using namespace std;
 
vector find_sequence(int n)
{
     
    // Base Case
    if (n == 1)
        return {1, -1};
 
    // Recursive Call for n-1
    auto arr = find_sequence(n - 1);
    vector ans = {arr[0] + 1, n - 1};
 
    // Check if n is divisible by 2
    if (n % 2 == 0)
    {
        vector div_by_2 = find_sequence(n / 2);
 
        if (div_by_2[0] < ans[0])
            ans = {div_by_2[0] + 1, n / 2};
    }
 
    // Check if n is divisible by 3
    if (n % 3 == 0)
    {
        vector div_by_3 = find_sequence(n / 3);
 
        if (div_by_3[0] < ans[0])
            vector ans = {div_by_3[0] + 1, n / 3};
    }
 
    // Returns a tuple (a, b), where
    // a: Minimum steps to obtain x from 1
    // b: Previous number
    return ans;
}
 
// Function that find the optimal
// solution
vector find_solution(int n)
{
    auto a = find_sequence(n);
 
    // Print the length
    cout << a[0] << endl;
 
    vector sequence;
    sequence.push_back(n);
 
    //Exit condition for loop = -1
    //when n has reached 1
    while (a[1] != -1)
    {
        sequence.push_back(a[1]);
        auto arr = find_sequence(a[1]);
        a[1] = arr[1];
    }
 
    // Return the sequence
    // in reverse order
    reverse(sequence.begin(),
            sequence.end());
 
    return sequence;
}
 
// Driver Code
int main()
{
     
    // Given N
    int n = 5;
     
    // Function call
    auto i = find_solution(n);
     
    for(int j : i)
        cout << j << " ";
}
 
// This code is contributed by mohit kumar 29


Java
// Java program to implement
// the above approach
import java.util.*;
import java.util.Collections;
import java.util.Vector;
 
//Vector v = new Vector(n);
 
class GFG{
   
static Vector find_sequence(int n)
{
    Vector temp = new Vector();
     
    temp.add(1);
    temp.add(-1);
     
    // Base Case
    if (n == 1)
        return temp;
     
    // Recursive Call for n-1
    Vector arr = find_sequence(n - 1);
    Vector ans = new Vector(n);
    ans.add(arr.get(0) + 1);
    ans.add(n - 1);
     
    // Check if n is divisible by 2
    if (n % 2 == 0)
    {
        Vector div_by_2 = find_sequence(n / 2);
         
        if (div_by_2.get(0) < ans.get(0))
        {
            ans.clear();
            ans.add(div_by_2.get(0) + 1);
            ans.add(n / 2);
        }
    }
 
    // Check if n is divisible by 3
    if (n % 3 == 0)
    {
        Vector div_by_3 = find_sequence(n / 3);
         
        if (div_by_3.get(0) < ans.get(0))
        {
            ans.clear();
            ans.add(div_by_3.get(0) + 1);
            ans.add(n / 3);
        }
    }
     
    // Returns a tuple (a, b), where
    // a: Minimum steps to obtain x from 1
    // b: Previous number
    return ans;
}
 
// Function that find the optimal
// solution
static Vector find_solution(int n)
{
    Vector a = find_sequence(n);
     
    // Print the length
    System.out.println(a.get(0));
     
    Vector sequence = new Vector();
    sequence.add(n);
     
    // Exit condition for loop = -1
    // when n has reached 1
    while (a.get(1) != -1)
    {
        sequence.add(a.get(1));
        Vector arr = find_sequence(a.get(1));
        a.set(1, arr.get(1));
    }
     
    // Return the sequence
    // in reverse order
    Collections.reverse(sequence);
     
    return sequence;
}
 
// Driver Code
public static void main(String args[])
{
     
    // Given N
    int n = 5;
     
    // Function call
    Vector res = find_solution(n);
     
    for(int i = 0; i < res.size(); i++)
    {
        System.out.print(res.get(i) + " ");
    }
}
}
 
// This code is contributed by Surendra_Gangwar


Python3
# Python3 program to implement
# the above approach
 
 
def find_sequence(n):
 
    # Base Case
    if n == 1:
        return 1, -1
  
    # Recursive Call for n-1
    ans = (find_sequence(n - 1)[0] + 1, n - 1)
  
    # Check if n is divisible by 2
    if n % 2 == 0:
        div_by_2 = find_sequence(n // 2)
 
        if div_by_2[0] < ans[0]:
            ans = (div_by_2[0] + 1, n // 2)
  
    # Check if n is divisible by 3
    if n % 3 == 0:
        div_by_3 = find_sequence(n // 3)
 
        if div_by_3[0] < ans[0]:
            ans = (div_by_3[0] + 1, n // 3)
  
    # Returns a tuple (a, b), where
    # a: Minimum steps to obtain x from 1
    # b: Previous number
    return ans
  
# Function that find the optimal
# solution
def find_solution(n):
    a, b = find_sequence(n)
  
    # Print the length
    print(a)
 
    sequence = []
    sequence.append(n)
 
    # Exit condition for loop = -1
    # when n has reached 1
    while b != -1:
        sequence.append(b)
        _, b = find_sequence(b)
  
    # Return the sequence
    # in reverse order
    return sequence[::-1]
 
# Driver Code
 
# Given N
n = 5
 
# Function Call
print(*find_solution(n))


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG{
   
static List find_sequence(int n)
{
  List temp = new List();
 
  temp.Add(1);
  temp.Add(-1);
 
  // Base Case
  if (n == 1)
    return temp;
 
  // Recursive Call for n-1
  List arr = find_sequence(n - 1);
  List ans = new List(n);
  ans.Add(arr[0] + 1);
  ans.Add(n - 1);
 
  // Check if n is divisible by 2
  if (n % 2 == 0)
  {
    List div_by_2 =
         find_sequence(n / 2);
 
    if (div_by_2[0] < ans[0])
    {
      ans.Clear();
      ans.Add(div_by_2[0] + 1);
      ans.Add(n / 2);
    }
  }
 
  // Check if n is divisible
  // by 3
  if (n % 3 == 0)
  {
    List div_by_3 =
         find_sequence(n / 3);
 
    if (div_by_3[0] < ans[0])
    {
      ans.Clear();
      ans.Add(div_by_3[0] + 1);
      ans.Add(n / 3);
    }
  }
 
  // Returns a tuple (a, b), where
  // a: Minimum steps to obtain x
  // from 1 b: Previous number
  return ans;
}
 
// Function that find the optimal
// solution
static List find_solution(int n)
{
  List a = find_sequence(n);
 
  // Print the length
  Console.WriteLine(a[0]);
 
  List sequence =
       new List();
  sequence.Add(n);
 
  // Exit condition for loop = -1
  // when n has reached 1
  while (a[1] != -1)
  {
    sequence.Add(a[1]);
    List arr =
         find_sequence(a[1]);
    a.Insert(1, arr[1]);
  }
 
  // Return the sequence
  // in reverse order
  sequence.Reverse();
  return sequence;
}
 
// Driver Code
public static void Main(String []args)
{   
  // Given N
  int n = 5;
 
  // Function call
  List res = find_solution(n);
 
  for(int i = 0; i < res.Count; i++)
  {
    Console.Write(res[i] + " ");
  }
}
}
 
// This code is contributed by shikhasingrajput


Python3
# Python3 program to implement
# the above approach
 
# Function to find the sequence
# with given operations
def find_sequence(n, map):
 
    # Base Case
    if n == 1:
        return 1, -1
 
    # Check if the subproblem
    # is already computed or not
    if n in map:
        return map[n]
 
    # Recursive Call for n-1
    ans = (find_sequence(n - 1, map)[0]\
    + 1, n - 1)
 
    # Check if n is divisible by 2
    if n % 2 == 0:
        div_by_2 = find_sequence(n // 2, map)
 
        if div_by_2[0] < ans[0]:
            ans = (div_by_2[0] + 1, n // 2)
 
    # Check if n is divisible by 3
    if n % 3 == 0:
        div_by_3 = find_sequence(n // 3, map)
 
        if div_by_3[0] < ans[0]:
            ans = (div_by_3[0] + 1, n // 3)
 
    # Memoize
    map[n] = ans
 
    # Returns a tuple (a, b), where
    # a: Minimum steps to obtain x from 1
    # b: Previous state
    return ans
 
# Function to check if a sequence can
# be obtained with given operations
def find_solution(n):
 
    # Stores the computed
    # subproblems
    map = {}
    a, b = find_sequence(n, map)
 
    # Return a sequence in
    # reverse order
    print(a)
    sequence = []
    sequence.append(n)
 
    # If n has reached 1
    while b != -1:
        sequence.append(b)
        _, b = find_sequence(b, map)
 
    # Return sequence in reverse order
    return sequence[::-1]
 
# Driver Code
 
# Given N
n = 5
 
# Function Call
print(*find_solution(n))


C++
// C++ program to implement
// the above approach
#include 
using namespace std;
 
// Function to generate
// the minimum sequence
void find_sequence(int n)
{
 
  // Stores the values for the
  // minimum length of sequences
  int dp[n + 1];
  memset(dp, 0, sizeof(dp));
 
  // Base Case
  dp[1] = 1;
 
  // Loop to build up the dp[]
  // array from 1 to n
  for(int i = 1; i < n + 1; i++)
  {
    if (dp[i] != 0)
    {
 
      // If i + 1 is within limits
      if (i + 1 < n + 1 &&
          (dp[i + 1] == 0 ||
           dp[i + 1] > dp[i] + 1))
      {
 
        // Update the state of i + 1
        // in dp[] array to minimum
        dp[i + 1] = dp[i] + 1;
      }
 
      // If i * 2 is within limits
      if (i * 2 < n + 1 &&
          (dp[i * 2] == 0 ||
           dp[i * 2] > dp[i] + 1))
      {
 
        // Update the state of i * 2
        // in dp[] array to minimum
        dp[i * 2] = dp[i] + 1;
      }
 
      // If i * 3 is within limits
      if (i * 3 < n + 1 &&
          (dp[i * 3] == 0 ||
           dp[i * 3] > dp[i] + 1))
      {
 
        // Update the state of i * 3
        // in dp[] array to minimum
        dp[i * 3] = dp[i] + 1;
      }
    }
  }
 
  // Generate the sequence by
  // traversing the array
  vector sequence;
  while (n >= 1)
  {
 
    // Append n to the sequence
    sequence.push_back(n);
 
    // If the value of n in dp
    // is obtained from n - 1:
    if (dp[n - 1] == dp[n] - 1)
    {
      n--;
    }
 
    // If the value of n in dp[]
    // is obtained from n / 2:
    else if (n % 2 == 0 &&
             dp[(int)floor(n / 2)] == dp[n] - 1)
    {
      n = (int)floor(n / 2);
    }
 
    // If the value of n in dp[]
    // is obtained from n / 3:
    else if (n % 3 == 0 &&
             dp[(int)floor(n / 3)] == dp[n] - 1)
    {
      n = (int)floor(n / 3);
    }
  }
 
  // Print the sequence
  // in reverse order
  reverse(sequence.begin(), sequence.end());
 
  // Print the length of
  // the minimal sequence
  cout << sequence.size() << endl;
  for(int i = 0; i < sequence.size(); i++)
  {
    cout << sequence[i] << " ";
  }
}
 
// Driver code
int main()
{
 
  // Given Number N
  int n = 5;
 
  // Function Call
  find_sequence(n);
 
  return 0;
}
 
// This code is contributed by divyeshrabadiya07


Java
// Java program to implement
// the above approach
import java.io.*;
import java.util.*;
 
class GFG{
     
// Function to generate
// the minimum sequence
public static void find_sequence(int n)
{
     
    // Stores the values for the
    // minimum length of sequences
    int[] dp = new int[n + 1];
    Arrays.fill(dp, 0);
     
    // Base Case
    dp[1] = 1;
     
    // Loop to build up the dp[]
    // array from 1 to n
    for(int i = 1; i < n + 1; i++)
    {
        if (dp[i] != 0)
        {
             
            // If i + 1 is within limits
            if (i + 1 < n + 1 &&
            (dp[i + 1] == 0 ||
             dp[i + 1] > dp[i] + 1))
            {
                 
                // Update the state of i + 1
                // in dp[] array to minimum
                dp[i + 1] = dp[i] + 1;
            }
             
            // If i * 2 is within limits
            if (i * 2 < n + 1 &&
            (dp[i * 2] == 0 ||
             dp[i * 2] > dp[i] + 1))
            {
                 
                // Update the state of i * 2
                // in dp[] array to minimum
                dp[i * 2] = dp[i] + 1;
            }
             
            // If i * 3 is within limits
            if (i * 3 < n + 1 &&
            (dp[i * 3] == 0 ||
             dp[i * 3] > dp[i] + 1))
            {
                 
                // Update the state of i * 3
                // in dp[] array to minimum
                dp[i * 3] = dp[i] + 1;
            }
        }
    }
     
    // Generate the sequence by
    // traversing the array
    List sequence = new ArrayList();
    while (n >= 1)
    {
         
        // Append n to the sequence
        sequence.add(n);
         
        // If the value of n in dp
        // is obtained from n - 1:
        if (dp[n - 1] == dp[n] - 1)
        {
            n--;
        }
         
        // If the value of n in dp[]
        // is obtained from n / 2:
        else if (n % 2 == 0 &&
         dp[(int)Math.floor(n / 2)] == dp[n] - 1)
        {
            n = (int)Math.floor(n / 2);
        }
         
        // If the value of n in dp[]
        // is obtained from n / 3:
        else if (n % 3 == 0 &&
         dp[(int)Math.floor(n / 3)] == dp[n] - 1)
        {
            n = (int)Math.floor(n / 3);
        }
    }
     
    // Print the sequence
    // in reverse order
    Collections.reverse(sequence);
     
    // Print the length of
    // the minimal sequence
    System.out.println(sequence.size());
    for(int i = 0; i < sequence.size(); i++)
    {
        System.out.print(sequence.get(i) + " ");
    }
}
 
// Driver Code
public static void main (String[] args)
{
     
    // Given Number N
    int n = 5;
     
    // Function Call
    find_sequence(n);
}
}
 
// This code is contributed by avanitrachhadiya2155


Python3
# Python3 program to implement
# the above approach
 
# Function to generate
# the minimum sequence
def find_sequence(n):
 
    # Stores the values for the
    # minimum length of sequences
    dp = [0 for _ in range(n + 1)]
 
    # Base Case
    dp[1] = 1
 
    # Loop to build up the dp[]
    # array from 1 to n
    for i in range(1, n + 1):
 
        if dp[i] != 0:
 
            # If i + 1 is within limits
            if i + 1 < n + 1 and (dp[i + 1] == 0 \
            or dp[i + 1] > dp[i] + 1):
                 
                # Update the state of i + 1
                # in dp[] array to minimum
                dp[i + 1] = dp[i] + 1
 
            # If i * 2 is within limits
            if i * 2 < n + 1 and (dp[i * 2] == 0 \
            or dp[i * 2] > dp[i] + 1):
                 
                # Update the state of i * 2
                # in dp[] array to minimum
                dp[i * 2] = dp[i] + 1
 
            # If i * 3 is within limits
            if i * 3 < n + 1 and (dp[i * 3] == 0 \
            or dp[i * 3] > dp[i] + 1):
                 
                # Update the state of i * 3
                # in dp[] array to minimum
                dp[i * 3] = dp[i] + 1
 
    # Generate the sequence by
    # traversing the array
    sequence = []
    while n >= 1:
 
        # Append n to the sequence
        sequence.append(n)
 
        # If the value of n in dp
        # is obtained from n - 1:
        if dp[n - 1] == dp[n] - 1:
            n = n - 1
 
        # If the value of n in dp[]
        # is obtained from n / 2:
        elif n % 2 == 0 \
        and dp[n // 2] == dp[n] - 1:
            n = n // 2
 
        # If the value of n in dp[]
        # is obtained from n / 3:
        elif n % 3 == 0 \
        and dp[n // 3] == dp[n] - 1:
            n = n // 3
 
    # Return the sequence
    # in reverse order
    return sequence[::-1]
 
# Driver Code
 
# Given Number N
n = 5
 
# Function Call
sequence = find_sequence(n)
 
# Print the length of
# the minimal sequence
print(len(sequence))
 
# Print the sequence
print(*sequence)


C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG
{
 
  // Function to generate
  // the minimum sequence
  public static void find_sequence(int n)
  {
 
    // Stores the values for the
    // minimum length of sequences
    int[] dp = new int[n + 1];
    Array.Fill(dp, 0);
 
    // Base Case
    dp[1] = 1;
 
    // Loop to build up the dp[]
    // array from 1 to n
    for(int i = 1; i < n + 1; i++)
    {
      if(dp[i] != 0)
      {
 
        // If i + 1 is within limits
        if(i + 1 < n + 1 &&
           (dp[i + 1] == 0 ||
            dp[i + 1] > dp[i] + 1))
        {
 
          // Update the state of i + 1
          // in dp[] array to minimum
          dp[i + 1] = dp[i] + 1;
        }
 
        // If i * 2 is within limits
        if(i * 2 < n + 1 &&
           (dp[i * 2] == 0 ||
            dp[i * 2] > dp[i] + 1))
        {
 
          // Update the state of i * 2
          // in dp[] array to minimum
          dp[i * 2] = dp[i] + 1;
        }
 
        // If i * 3 is within limits
        if(i * 3 < n + 1 &&
           (dp[i * 3] == 0 ||
            dp[i * 3] > dp[i] + 1))
        {
 
          // Update the state of i * 3
          // in dp[] array to minimum
          dp[i * 3] = dp[i] + 1;
        }       
      }
    }
 
    // Generate the sequence by
    // traversing the array
    List sequence = new List();
    while(n >= 1)
    {
 
      // Append n to the sequence
      sequence.Add(n);
 
      // If the value of n in dp
      // is obtained from n - 1:
      if(dp[n - 1] == dp[n] - 1)
      {
        n--;
      }
 
      // If the value of n in dp[]
      // is obtained from n / 2:
      else if(n % 2 == 0 &&
              dp[(int)Math.Floor((decimal)n / 2)] ==
              dp[n] - 1)
      {
        n = (int)Math.Floor((decimal)n / 2);
      }
 
      // If the value of n in dp[]
      // is obtained from n / 3:
      else if(n % 3 == 0 &&
              dp[(int)Math.Floor((decimal)n / 3)] ==
              dp[n] - 1)
      {
        n = (int)Math.Floor((decimal)n / 3);
      }
 
    }
 
    // Print the sequence
    // in reverse order
    sequence.Reverse();
 
    // Print the length of
    // the minimal sequence
    Console.WriteLine(sequence.Count);
    for(int i = 0; i < sequence.Count; i++)
    {
      Console.Write(sequence[i] + " ");
    }
  }
 
  // Driver Code
  static public void Main ()
  {
 
    // Given Number N
    int n = 5;
 
    // Function Call
    find_sequence(n);
  }
}
 
// This code is contributed by rag2127


输出:
4
1 2 4 5

时间复杂度: T(N)= T(N-1)+ T(N / 2)+ T(N / 3),其中N为整数。该算法导致指数时间复杂度。

辅助空间: O(1)

带有记忆方法的递归可以通过记忆重叠的子问题来优化上述方法。

下面是上述方法的实现:

Python3

# Python3 program to implement
# the above approach
 
# Function to find the sequence
# with given operations
def find_sequence(n, map):
 
    # Base Case
    if n == 1:
        return 1, -1
 
    # Check if the subproblem
    # is already computed or not
    if n in map:
        return map[n]
 
    # Recursive Call for n-1
    ans = (find_sequence(n - 1, map)[0]\
    + 1, n - 1)
 
    # Check if n is divisible by 2
    if n % 2 == 0:
        div_by_2 = find_sequence(n // 2, map)
 
        if div_by_2[0] < ans[0]:
            ans = (div_by_2[0] + 1, n // 2)
 
    # Check if n is divisible by 3
    if n % 3 == 0:
        div_by_3 = find_sequence(n // 3, map)
 
        if div_by_3[0] < ans[0]:
            ans = (div_by_3[0] + 1, n // 3)
 
    # Memoize
    map[n] = ans
 
    # Returns a tuple (a, b), where
    # a: Minimum steps to obtain x from 1
    # b: Previous state
    return ans
 
# Function to check if a sequence can
# be obtained with given operations
def find_solution(n):
 
    # Stores the computed
    # subproblems
    map = {}
    a, b = find_sequence(n, map)
 
    # Return a sequence in
    # reverse order
    print(a)
    sequence = []
    sequence.append(n)
 
    # If n has reached 1
    while b != -1:
        sequence.append(b)
        _, b = find_sequence(b, map)
 
    # Return sequence in reverse order
    return sequence[::-1]
 
# Driver Code
 
# Given N
n = 5
 
# Function Call
print(*find_solution(n))
输出:
4
1 2 4 5

时间复杂度: O(N)
辅助空间: O(N)

迭代动态规划方法:可以通过使用迭代DP方法进一步优化上述方法。请按照以下步骤解决问题:

  1. 创建一个数组dp []来存储三个可用操作计算1到N所需的最小序列长度。
  2. 一旦计算了dp []数组,就可以通过将dp []数组从N遍历到1来获得序列。

下面是上述方法的实现:

C++

// C++ program to implement
// the above approach
#include 
using namespace std;
 
// Function to generate
// the minimum sequence
void find_sequence(int n)
{
 
  // Stores the values for the
  // minimum length of sequences
  int dp[n + 1];
  memset(dp, 0, sizeof(dp));
 
  // Base Case
  dp[1] = 1;
 
  // Loop to build up the dp[]
  // array from 1 to n
  for(int i = 1; i < n + 1; i++)
  {
    if (dp[i] != 0)
    {
 
      // If i + 1 is within limits
      if (i + 1 < n + 1 &&
          (dp[i + 1] == 0 ||
           dp[i + 1] > dp[i] + 1))
      {
 
        // Update the state of i + 1
        // in dp[] array to minimum
        dp[i + 1] = dp[i] + 1;
      }
 
      // If i * 2 is within limits
      if (i * 2 < n + 1 &&
          (dp[i * 2] == 0 ||
           dp[i * 2] > dp[i] + 1))
      {
 
        // Update the state of i * 2
        // in dp[] array to minimum
        dp[i * 2] = dp[i] + 1;
      }
 
      // If i * 3 is within limits
      if (i * 3 < n + 1 &&
          (dp[i * 3] == 0 ||
           dp[i * 3] > dp[i] + 1))
      {
 
        // Update the state of i * 3
        // in dp[] array to minimum
        dp[i * 3] = dp[i] + 1;
      }
    }
  }
 
  // Generate the sequence by
  // traversing the array
  vector sequence;
  while (n >= 1)
  {
 
    // Append n to the sequence
    sequence.push_back(n);
 
    // If the value of n in dp
    // is obtained from n - 1:
    if (dp[n - 1] == dp[n] - 1)
    {
      n--;
    }
 
    // If the value of n in dp[]
    // is obtained from n / 2:
    else if (n % 2 == 0 &&
             dp[(int)floor(n / 2)] == dp[n] - 1)
    {
      n = (int)floor(n / 2);
    }
 
    // If the value of n in dp[]
    // is obtained from n / 3:
    else if (n % 3 == 0 &&
             dp[(int)floor(n / 3)] == dp[n] - 1)
    {
      n = (int)floor(n / 3);
    }
  }
 
  // Print the sequence
  // in reverse order
  reverse(sequence.begin(), sequence.end());
 
  // Print the length of
  // the minimal sequence
  cout << sequence.size() << endl;
  for(int i = 0; i < sequence.size(); i++)
  {
    cout << sequence[i] << " ";
  }
}
 
// Driver code
int main()
{
 
  // Given Number N
  int n = 5;
 
  // Function Call
  find_sequence(n);
 
  return 0;
}
 
// This code is contributed by divyeshrabadiya07

Java

// Java program to implement
// the above approach
import java.io.*;
import java.util.*;
 
class GFG{
     
// Function to generate
// the minimum sequence
public static void find_sequence(int n)
{
     
    // Stores the values for the
    // minimum length of sequences
    int[] dp = new int[n + 1];
    Arrays.fill(dp, 0);
     
    // Base Case
    dp[1] = 1;
     
    // Loop to build up the dp[]
    // array from 1 to n
    for(int i = 1; i < n + 1; i++)
    {
        if (dp[i] != 0)
        {
             
            // If i + 1 is within limits
            if (i + 1 < n + 1 &&
            (dp[i + 1] == 0 ||
             dp[i + 1] > dp[i] + 1))
            {
                 
                // Update the state of i + 1
                // in dp[] array to minimum
                dp[i + 1] = dp[i] + 1;
            }
             
            // If i * 2 is within limits
            if (i * 2 < n + 1 &&
            (dp[i * 2] == 0 ||
             dp[i * 2] > dp[i] + 1))
            {
                 
                // Update the state of i * 2
                // in dp[] array to minimum
                dp[i * 2] = dp[i] + 1;
            }
             
            // If i * 3 is within limits
            if (i * 3 < n + 1 &&
            (dp[i * 3] == 0 ||
             dp[i * 3] > dp[i] + 1))
            {
                 
                // Update the state of i * 3
                // in dp[] array to minimum
                dp[i * 3] = dp[i] + 1;
            }
        }
    }
     
    // Generate the sequence by
    // traversing the array
    List sequence = new ArrayList();
    while (n >= 1)
    {
         
        // Append n to the sequence
        sequence.add(n);
         
        // If the value of n in dp
        // is obtained from n - 1:
        if (dp[n - 1] == dp[n] - 1)
        {
            n--;
        }
         
        // If the value of n in dp[]
        // is obtained from n / 2:
        else if (n % 2 == 0 &&
         dp[(int)Math.floor(n / 2)] == dp[n] - 1)
        {
            n = (int)Math.floor(n / 2);
        }
         
        // If the value of n in dp[]
        // is obtained from n / 3:
        else if (n % 3 == 0 &&
         dp[(int)Math.floor(n / 3)] == dp[n] - 1)
        {
            n = (int)Math.floor(n / 3);
        }
    }
     
    // Print the sequence
    // in reverse order
    Collections.reverse(sequence);
     
    // Print the length of
    // the minimal sequence
    System.out.println(sequence.size());
    for(int i = 0; i < sequence.size(); i++)
    {
        System.out.print(sequence.get(i) + " ");
    }
}
 
// Driver Code
public static void main (String[] args)
{
     
    // Given Number N
    int n = 5;
     
    // Function Call
    find_sequence(n);
}
}
 
// This code is contributed by avanitrachhadiya2155

Python3

# Python3 program to implement
# the above approach
 
# Function to generate
# the minimum sequence
def find_sequence(n):
 
    # Stores the values for the
    # minimum length of sequences
    dp = [0 for _ in range(n + 1)]
 
    # Base Case
    dp[1] = 1
 
    # Loop to build up the dp[]
    # array from 1 to n
    for i in range(1, n + 1):
 
        if dp[i] != 0:
 
            # If i + 1 is within limits
            if i + 1 < n + 1 and (dp[i + 1] == 0 \
            or dp[i + 1] > dp[i] + 1):
                 
                # Update the state of i + 1
                # in dp[] array to minimum
                dp[i + 1] = dp[i] + 1
 
            # If i * 2 is within limits
            if i * 2 < n + 1 and (dp[i * 2] == 0 \
            or dp[i * 2] > dp[i] + 1):
                 
                # Update the state of i * 2
                # in dp[] array to minimum
                dp[i * 2] = dp[i] + 1
 
            # If i * 3 is within limits
            if i * 3 < n + 1 and (dp[i * 3] == 0 \
            or dp[i * 3] > dp[i] + 1):
                 
                # Update the state of i * 3
                # in dp[] array to minimum
                dp[i * 3] = dp[i] + 1
 
    # Generate the sequence by
    # traversing the array
    sequence = []
    while n >= 1:
 
        # Append n to the sequence
        sequence.append(n)
 
        # If the value of n in dp
        # is obtained from n - 1:
        if dp[n - 1] == dp[n] - 1:
            n = n - 1
 
        # If the value of n in dp[]
        # is obtained from n / 2:
        elif n % 2 == 0 \
        and dp[n // 2] == dp[n] - 1:
            n = n // 2
 
        # If the value of n in dp[]
        # is obtained from n / 3:
        elif n % 3 == 0 \
        and dp[n // 3] == dp[n] - 1:
            n = n // 3
 
    # Return the sequence
    # in reverse order
    return sequence[::-1]
 
# Driver Code
 
# Given Number N
n = 5
 
# Function Call
sequence = find_sequence(n)
 
# Print the length of
# the minimal sequence
print(len(sequence))
 
# Print the sequence
print(*sequence)

C#

// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
class GFG
{
 
  // Function to generate
  // the minimum sequence
  public static void find_sequence(int n)
  {
 
    // Stores the values for the
    // minimum length of sequences
    int[] dp = new int[n + 1];
    Array.Fill(dp, 0);
 
    // Base Case
    dp[1] = 1;
 
    // Loop to build up the dp[]
    // array from 1 to n
    for(int i = 1; i < n + 1; i++)
    {
      if(dp[i] != 0)
      {
 
        // If i + 1 is within limits
        if(i + 1 < n + 1 &&
           (dp[i + 1] == 0 ||
            dp[i + 1] > dp[i] + 1))
        {
 
          // Update the state of i + 1
          // in dp[] array to minimum
          dp[i + 1] = dp[i] + 1;
        }
 
        // If i * 2 is within limits
        if(i * 2 < n + 1 &&
           (dp[i * 2] == 0 ||
            dp[i * 2] > dp[i] + 1))
        {
 
          // Update the state of i * 2
          // in dp[] array to minimum
          dp[i * 2] = dp[i] + 1;
        }
 
        // If i * 3 is within limits
        if(i * 3 < n + 1 &&
           (dp[i * 3] == 0 ||
            dp[i * 3] > dp[i] + 1))
        {
 
          // Update the state of i * 3
          // in dp[] array to minimum
          dp[i * 3] = dp[i] + 1;
        }       
      }
    }
 
    // Generate the sequence by
    // traversing the array
    List sequence = new List();
    while(n >= 1)
    {
 
      // Append n to the sequence
      sequence.Add(n);
 
      // If the value of n in dp
      // is obtained from n - 1:
      if(dp[n - 1] == dp[n] - 1)
      {
        n--;
      }
 
      // If the value of n in dp[]
      // is obtained from n / 2:
      else if(n % 2 == 0 &&
              dp[(int)Math.Floor((decimal)n / 2)] ==
              dp[n] - 1)
      {
        n = (int)Math.Floor((decimal)n / 2);
      }
 
      // If the value of n in dp[]
      // is obtained from n / 3:
      else if(n % 3 == 0 &&
              dp[(int)Math.Floor((decimal)n / 3)] ==
              dp[n] - 1)
      {
        n = (int)Math.Floor((decimal)n / 3);
      }
 
    }
 
    // Print the sequence
    // in reverse order
    sequence.Reverse();
 
    // Print the length of
    // the minimal sequence
    Console.WriteLine(sequence.Count);
    for(int i = 0; i < sequence.Count; i++)
    {
      Console.Write(sequence[i] + " ");
    }
  }
 
  // Driver Code
  static public void Main ()
  {
 
    // Given Number N
    int n = 5;
 
    // Function Call
    find_sequence(n);
  }
}
 
// This code is contributed by rag2127
输出:
4
1 3 4 5

时间复杂度: O(N)
辅助空间: O(N)