给定一个整数 N ,任务是通过执行以下两个操作来计算将N的值减少到0所需的最小步骤:
- 考虑整数A和B ,其中N = A * B (A != 1 and B != 1),将N减少到min(A, B)
- 将N的值减少1
例子 :
Input: N = 3
Output: 3
Explanation:
Steps involved are 3 -> 2 -> 1 -> 0
Therefore, the minimum steps required is 3.
Input: N = 4
Output: 3
Explanation:
Steps involved are 4->2->1->0.
Therefore, the minimum steps required is 3.
朴素的方法:这个想法是使用动态规划的概念。请按照以下步骤解决问题:
- 这个问题的简单解决方案是用每个可能的值替换N ,直到它不为 0。
- 当N达到 0 时,将移动次数与迄今为止获得的最小值进行比较,以获得最佳答案。
- 最后,打印计算出的最小步数。
Illustration:
N = 4,
- On applying the first rule, factors of 4 are [ 1, 2, 4 ].
Therefore, all possible pairs (a, b) are (1 * 4), (2 * 2), (4 * 1).
Only pair satisfying the condition (a!=1 and b!=1) is (2, 2) . Therefore, reduce 4 to 2.
Finally, reduce N to 0, in 3 steps(4 -> 2 -> 1 -> 0) - On applying the second rule, steps required is 4, (4 -> 3 -> 2 -> 1 -> 0).
- Therefore, minimum steps required to reduce N to 0 is 3.
因此,关系为:
f(N) = 1 + min( f(N-1), min(f(x)) ), where N % x == 0 and x is in range [2, K] where K = sqrt(N)
下面是上述方法的实现:
C++
Recursive tree for N = 4 is
4
/ \
3 2(2*2)
| |
2 1
| |
1 0
|
0
Java
// C++ Program to implement
// the above approach
#include
using namespace std;
// Function to count the minimum
// steps required to reduce n
int downToZero(int n)
{
// Base case
if (n <= 3)
return n;
// Allocate memory for storing
// intermediate results
vector dp(n + 1, -1);
// Store base values
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
// Stores square root
// of each number
int sqr;
for (int i = 4; i <= n; i++) {
// Compute square root
sqr = sqrt(i);
int best = INT_MAX;
// Use rule 1 to find optimized
// answer
while (sqr > 1) {
// Check if it perfectly divides n
if (i % sqr == 0) {
best = min(best, 1 + dp[sqr]);
}
sqr--;
}
// Use of rule 2 to find
// the optimized answer
best = min(best, 1 + dp[i - 1]);
// Store computed value
dp[i] = best;
}
// Return answer
return dp[n];
}
// Driver Code
int main()
{
int n = 4;
cout << downToZero(n);
return 0;
}
Python3
// Java program to implement
// the above approach
class GFG{
// Function to count the minimum
// steps required to reduce n
static int downToZero(int n)
{
// Base case
if (n <= 3)
return n;
// Allocate memory for storing
// intermediate results
int []dp = new int[n + 1];
for(int i = 0; i < n + 1; i++)
dp[i] = -1;
// Store base values
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
// Stores square root
// of each number
int sqr;
for(int i = 4; i <= n; i++)
{
// Compute square root
sqr = (int)Math.sqrt(i);
int best = Integer.MAX_VALUE;
// Use rule 1 to find optimized
// answer
while (sqr > 1)
{
// Check if it perfectly divides n
if (i % sqr == 0)
{
best = Math.min(best, 1 + dp[sqr]);
}
sqr--;
}
// Use of rule 2 to find
// the optimized answer
best = Math.min(best, 1 + dp[i - 1]);
// Store computed value
dp[i] = best;
}
// Return answer
return dp[n];
}
// Driver Code
public static void main(String[] args)
{
int n = 4;
System.out.print(downToZero(n));
}
}
// This code is contributed by amal kumar choubey
C#
# Python3 program to implement
# the above approach
import math
import sys
# Function to count the minimum
# steps required to reduce n
def downToZero(n):
# Base case
if (n <= 3):
return n
# Allocate memory for storing
# intermediate results
dp = [-1] * (n + 1)
# Store base values
dp[0] = 0
dp[1] = 1
dp[2] = 2
dp[3] = 3
# Stores square root
# of each number
for i in range(4, n + 1):
# Compute square root
sqr = (int)(math.sqrt(i))
best = sys.maxsize
# Use rule 1 to find optimized
# answer
while (sqr > 1):
# Check if it perfectly divides n
if (i % sqr == 0):
best = min(best, 1 + dp[sqr])
sqr -= 1
# Use of rule 2 to find
# the optimized answer
best = min(best, 1 + dp[i - 1])
# Store computed value
dp[i] = best
# Return answer
return dp[n]
# Driver Code
if __name__ == "__main__":
n = 4
print(downToZero(n))
# This code is contributed by chitranayal
Javascript
// C# program to implement
// the above approach
using System;
class GFG{
// Function to count the minimum
// steps required to reduce n
static int downToZero(int n)
{
// Base case
if (n <= 3)
return n;
// Allocate memory for storing
// intermediate results
int []dp = new int[n + 1];
for(int i = 0; i < n + 1; i++)
dp[i] = -1;
// Store base values
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
// Stores square root
// of each number
int sqr;
for(int i = 4; i <= n; i++)
{
// Compute square root
sqr = (int)Math.Sqrt(i);
int best = int.MaxValue;
// Use rule 1 to find optimized
// answer
while (sqr > 1)
{
// Check if it perfectly divides n
if (i % sqr == 0)
{
best = Math.Min(best, 1 + dp[sqr]);
}
sqr--;
}
// Use of rule 2 to find
// the optimized answer
best = Math.Min(best, 1 + dp[i - 1]);
// Store computed value
dp[i] = best;
}
// Return answer
return dp[n];
}
// Driver Code
public static void Main(String[] args)
{
int n = 4;
Console.Write(downToZero(n));
}
}
// This code is contributed by amal kumar choubey
C++
Java
// C++ Program to implement
// the above approach
#include
using namespace std;
// Function to find the minimum
// steps required to reduce n
int downToZero(int n)
{
// Base case
if (n <= 3)
return n;
// Return answer based on
// parity of n
return n % 2 == 0 ? 3 : 4;
}
// Driver Code
int main()
{
int n = 4;
cout << downToZero(n);
return 0;
}
Python3
// Java Program to implement
// the above approach
class GFG{
// Function to find the minimum
// steps required to reduce n
static int downToZero(int n)
{
// Base case
if (n <= 3)
return n;
// Return answer based on
// parity of n
return n % 2 == 0 ? 3 : 4;
}
// Driver Code
public static void main(String[] args)
{
int n = 4;
System.out.println(downToZero(n));
}
}
// This code is contributed by rock_cool
C#
# Python3 Program to implement
# the above approach
# Function to find the minimum
# steps required to reduce n
def downToZero(n):
# Base case
if (n <= 3):
return n;
# Return answer based on
# parity of n
if(n % 2 == 0):
return 3;
else:
return 4;
# Driver Code
if __name__ == '__main__':
n = 4;
print(downToZero(n));
# This code is contributed by Rohit_ranjan
Javascript
// C# Program to implement
// the above approach
using System;
class GFG{
// Function to find the minimum
// steps required to reduce n
static int downToZero(int n)
{
// Base case
if (n <= 3)
return n;
// Return answer based on
// parity of n
return n % 2 == 0 ? 3 : 4;
}
// Driver Code
public static void Main(String[] args)
{
int n = 4;
Console.WriteLine(downToZero(n));
}
}
// This code is contributed by Rajput-Ji
输出:
时间复杂度: O(N * sqrt(n))
辅助空间: O(N)
有效的方法:这个想法是观察可以用 N’ 替换 N,其中 N’ = min(a, b) (N = a * b) (a != 1 and b != 1)。
- 如果N 是偶数,则除以N的最小值是2 。因此,直接计算f(N) = 1 + f(2) = 3。
- 如果N 是奇数,则将N减去1 ,即N = N – 1 。应用与偶数相同的逻辑。因此,对于奇数,所需的最小步长为4 。
下面是上述方法的实现:
C++
3
Java
// C++ Program to implement
// the above approach
#include
using namespace std;
// Function to find the minimum
// steps required to reduce n
int downToZero(int n)
{
// Base case
if (n <= 3)
return n;
// Return answer based on
// parity of n
return n % 2 == 0 ? 3 : 4;
}
// Driver Code
int main()
{
int n = 4;
cout << downToZero(n);
return 0;
}
蟒蛇3
// Java Program to implement
// the above approach
class GFG{
// Function to find the minimum
// steps required to reduce n
static int downToZero(int n)
{
// Base case
if (n <= 3)
return n;
// Return answer based on
// parity of n
return n % 2 == 0 ? 3 : 4;
}
// Driver Code
public static void main(String[] args)
{
int n = 4;
System.out.println(downToZero(n));
}
}
// This code is contributed by rock_cool
C#
# Python3 Program to implement
# the above approach
# Function to find the minimum
# steps required to reduce n
def downToZero(n):
# Base case
if (n <= 3):
return n;
# Return answer based on
# parity of n
if(n % 2 == 0):
return 3;
else:
return 4;
# Driver Code
if __name__ == '__main__':
n = 4;
print(downToZero(n));
# This code is contributed by Rohit_ranjan
Javascript
// C# Program to implement
// the above approach
using System;
class GFG{
// Function to find the minimum
// steps required to reduce n
static int downToZero(int n)
{
// Base case
if (n <= 3)
return n;
// Return answer based on
// parity of n
return n % 2 == 0 ? 3 : 4;
}
// Driver Code
public static void Main(String[] args)
{
int n = 4;
Console.WriteLine(downToZero(n));
}
}
// This code is contributed by Rajput-Ji
输出:
时间复杂度: O(1)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。