给定整数N ,任务是找到从1开始获得数N所需的最小操作数。以下是操作:
- 在当前数字上加1。
- 将当前数字乘以2。
- 将当前数字乘以3。
打印所需的最少操作数以及获得N的相应顺序。
例子:
Input: N = 3
Output:
1
1 3
Explanation:
Operation 1: Multiply 1 * 3 = 3.
Hence, only 1 operation is required.
Input: N = 5
Output:
3
1 2 4 5
Explanation:
The minimum required operations are as follows:
1 * 2 -> 2
2 * 2 -> 4
4 + 1 -> 5
递归方法:递归地生成每种可能的组合,以将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方法进一步优化上述方法。请按照以下步骤解决问题:
- 创建一个数组dp []来存储三个可用操作计算1到N所需的最小序列长度。
- 一旦计算了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)