给定一个由N 个正整数组成的数组arr[] 和一个正整数K ,任务是通过将任何数组元素增加或减少K来最大化数组arr[]的 GCD。
例子:
Input: arr[] = {3, 9, 15, 24}, K = 1
Output: 4
Explanation:
Perform the following operations on the array arr[]:
Increment arr[0] by 1. Therefore, arr[] modifies to {4, 9, 15, 24}.
Decrement arr[1] by 1. Therefore, arr[] modifies to {4, 8, 15, 24}.
Increment arr[2] by 1. Therefore, arr[] modifies to {4, 8, 16, 24}.
Therefore, GCD of the modified array is 4.
Input: arr[] = {5, 9, 2}, K = 1
Output: 3
朴素的方法:解决这个问题的最简单的方法是考虑每个数组元素arr[i] 的所有三个选项,即,将arr[i]增加K ,将arr[i]减少K或既不增加也不减少arr[i] ] 。使用递归生成所有 3 种情况下形成的数组,并打印获得的所有数组的 GCD 的最大值。
时间复杂度: O(3 N )
辅助空间: O(1)
高效方法:上述方法可以使用动态规划进行优化。请按照以下步骤解决给定的问题:
- 初始化一个辅助数组,比如dp[][3] ,其中dp[i][0] 、 dp[i][1]和dp[i][2]表示通过不改变达到第i个索引的最大 GCD第i个元素,分别将第i个元素增加或减少K。
- 通过使用arr[0] 、 arr[0] + K和arr更新dp[0][0] 、 dp[0][1]和dp[0][2]来填充dp[][3]的第一行[0] – K分别。
- 迭代范围[1, N – 1]并执行以下步骤:
- 对于dp[i][0] ,找到具有 3 个先前状态的A[i]的最大 GCD,即dp[i – 1][0]、dp[i – 1][1]和dp[i – 1 ][2]一次,并将最大结果存储在dp[i][0] 中。
- 类似地,分别取(arr[i] + K)和(arr[i] – K)将结果存储在dp[i][1]和dp[i][2] 中。
- 完成上述步骤后,打印dp[N-1]行的最大值作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to return the maximum GCD
// by taking each operation
int findGCD(int x, int y, int z, int res)
{
// Store the maximum GCD obtained
// by either incrementing, decrementing
// or not changing A[i]
int ans = __gcd(x, res);
ans = max(ans, __gcd(y, res));
ans = max(ans, __gcd(z, res));
// Return the maximum GCD
return ans;
}
// Function to find the maximum GCD of
// the array arrA[] by either increasing
// or decreasing the array elements by K
int maximumGCD(int A[], int N, int K)
{
// Initialize a dp table of size N*3
int dp[N][3];
memset(dp, 0, sizeof(dp));
// Base Cases:
// If only one element is present
dp[0][0] = A[0];
dp[0][1] = A[0] + K;
dp[0][2] = A[0] - K;
// Traverse the array A[] over indices [1, N - 1]
for (int i = 1; i < N; i++) {
// Store the previous state results
int x = dp[i - 1][0];
int y = dp[i - 1][1];
int z = dp[i - 1][2];
// Store maximum GCD result
// for each current state
dp[i][0] = findGCD(x, y, z, A[i]);
dp[i][1] = findGCD(x, y, z, A[i] + K);
dp[i][2] = findGCD(x, y, z, A[i] - K);
}
// Store the required result
int mx = max(
{ 3, dp[N - 1][0], dp[N - 1][1],
dp[N - 1][2] });
// Return the result
return mx;
}
// Driver Code
int main()
{
int arr[] = { 3, 9, 15, 24 };
int K = 1;
int N = sizeof(arr) / sizeof(arr[0]);
cout << maximumGCD(arr, N, K);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.util.*;
class GFG
{
// Recursive function to return gcd of a and b
static int gcd(int a, int b)
{
// Everything divides 0
if (a == 0)
return b;
if (b == 0)
return a;
// base case
if (a == b)
return a;
// a is greater
if (a > b)
return gcd(a-b, b);
return gcd(a, b-a);
}
// Function to return the maximum GCD
// by taking each operation
static int findGCD(int x, int y, int z, int res)
{
// Store the maximum GCD obtained
// by either incrementing, decrementing
// or not changing A[i]
int ans = gcd(x, res);
ans = Math.max(ans, gcd(y, res));
ans = Math.max(ans, gcd(z, res));
// Return the maximum GCD
return ans;
}
// Function to find the maximum GCD of
// the array arrA[] by either increasing
// or decreasing the array elements by K
static int maximumGCD(int A[], int N, int K)
{
// Initialize a dp table of size N*3
int dp[][] = new int[N][3];
for (int i = 0; i < N; i++) {
for (int j = 1; j < 3; j++) {
dp[i][j] = 0;
}
}
// Base Cases:
// If only one element is present
dp[0][0] = A[0];
dp[0][1] = A[0] + K;
dp[0][2] = A[0] - K;
// Traverse the array A[] over indices [1, N - 1]
for (int i = 1; i < N; i++) {
// Store the previous state results
int x = dp[i - 1][0];
int y = dp[i - 1][1];
int z = dp[i - 1][2];
// Store maximum GCD result
// for each current state
dp[i][0] = findGCD(x, y, z, A[i]);
dp[i][1] = findGCD(x, y, z, A[i] + K);
dp[i][2] = findGCD(x, y, z, A[i] - K);
}
// Store the required result
int mx = Math.max(3, Math.max(dp[N - 1][0], Math.max(dp[N - 1][1],
dp[N - 1][2])));
// Return the result
return mx;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 3, 9, 15, 24 };
int K = 1;
int N = arr.length;
System.out.print( maximumGCD(arr, N, K));
}
}
// This code is contributed by sanjoy_62.
Python3
# Python3 program for the above approach
import math
# Function to return the maximum GCD
# by taking each operation
def findGCD(x, y, z, res):
# Store the maximum GCD obtained
# by either incrementing, decrementing
# or not changing A[i]
ans = math.gcd(x, res)
ans = max(ans, math.gcd(y, res))
ans = max(ans, math.gcd(z, res))
# Return the maximum GCD
return ans
# Function to find the maximum GCD of
# the array arrA[] by either increasing
# or decreasing the array elements by K
def maximumGCD(A, N, K):
# Initialize a dp table of size N*3
dp = [[0 for x in range(3)]
for y in range(N)]
# Base Cases:
# If only one element is present
dp[0][0] = A[0]
dp[0][1] = A[0] + K
dp[0][2] = A[0] - K
# Traverse the array A[] over
# indices [1, N - 1]
for i in range(1, N):
# Store the previous state results
x = dp[i - 1][0]
y = dp[i - 1][1]
z = dp[i - 1][2]
# Store maximum GCD result
# for each current state
dp[i][0] = findGCD(x, y, z, A[i])
dp[i][1] = findGCD(x, y, z, A[i] + K)
dp[i][2] = findGCD(x, y, z, A[i] - K)
# Store the required result
mx = max([3, dp[N - 1][0],
dp[N - 1][1],
dp[N - 1][2]])
# Return the result
return mx
# Driver Code
if __name__ == "__main__":
arr = [ 3, 9, 15, 24 ]
K = 1
N = len(arr)
print(maximumGCD(arr, N, K))
# This code is contributed by chitranayal
C#
// C# program to implement
// the above approach
using System;
class GFG
{
// Recursive function to return gcd of a and b
static int gcd(int a, int b)
{
// Everything divides 0
if (a == 0)
return b;
if (b == 0)
return a;
// base case
if (a == b)
return a;
// a is greater
if (a > b)
return gcd(a-b, b);
return gcd(a, b-a);
}
// Function to return the maximum GCD
// by taking each operation
static int findGCD(int x, int y, int z, int res)
{
// Store the maximum GCD obtained
// by either incrementing, decrementing
// or not changing A[i]
int ans = gcd(x, res);
ans = Math.Max(ans, gcd(y, res));
ans = Math.Max(ans, gcd(z, res));
// Return the maximum GCD
return ans;
}
// Function to find the maximum GCD of
// the array arrA[] by either increasing
// or decreasing the array elements by K
static int maximumGCD(int[] A, int N, int K)
{
// Initialize a dp table of size N*3
int[,] dp = new int[N, 3];
for (int i = 0; i < N; i++) {
for (int j = 1; j < 3; j++) {
dp[i, j] = 0;
}
}
// Base Cases:
// If only one element is present
dp[0, 0] = A[0];
dp[0, 1] = A[0] + K;
dp[0, 2] = A[0] - K;
// Traverse the array A[] over indices [1, N - 1]
for (int i = 1; i < N; i++) {
// Store the previous state results
int x = dp[i - 1, 0];
int y = dp[i - 1, 1];
int z = dp[i - 1, 2];
// Store maximum GCD result
// for each current state
dp[i, 0] = findGCD(x, y, z, A[i]);
dp[i, 1] = findGCD(x, y, z, A[i] + K);
dp[i, 2] = findGCD(x, y, z, A[i] - K);
}
// Store the required result
int mx = Math.Max(3, Math.Max(dp[N - 1, 0], Math.Max(dp[N - 1, 1],
dp[N - 1, 2])));
// Return the result
return mx;
}
// Driver code
public static void Main()
{
int[] arr = { 3, 9, 15, 24 };
int K = 1;
int N = arr.Length;
Console.Write( maximumGCD(arr, N, K));
}
}
// This code is contributed by susmitakundugoaldanga.
Javascript
4
时间复杂度: O(N*log(M)),其中M是数组arr[] 中的最小元素
辅助空间: O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。