Find out the maximum value of the expression according to the given constraint
Last Updated :
09 Dec, 2023
Given an array A[] of length N. Then your task is to output the maximum value of (Sum/LCM). Where Sum is the addition of all the elements of A[] and LCM is a number between [1, ∞] that can’t be achieved by any possible non-empty set of A[].
Examples:
Input: N = 5, A[] = {1, 2, 3, 4, 5}
Output: 2
Explanation:
- The Sum of A[] is = 1+2+3+4+5 = 15
- All the LCMs from 1 to 6 can be achieved from sets {1}, {2}, {3}, {4}, {5}, {2, 3} respectively. 7 is the LCM that can’t be achieved from any set of elements from A[]. Thus, LCM = 7
- Maximum value of (Sum/LCM) = 15/7 = 2
It can be verified that no maximum value from 2 can be achieved for the given expression. Thus, output is 2.
Input: N = 3, A[] = {4, 1, 2}
Output: 2
Explanation: It can be verified that the maximum possible value of expression will be 2.
Approach: Implement the idea below to solve the problem
The problem is observation based. For maximizing the (Sum/LCM) the numerator must be maximum possible and denominator must be minimum possible. We know that we can’t maximize Sum after addition of all the elements, we can consider it as a constant value that can’t be exceed after summing up all the elements. Now, the thinking comes over here is that we need to minimize the denominator. This thinking gives us approach that we have to find the minimum possible LCM under the range [1, ∞] that can’t be achieved by any non-empty set of elements of A[] or first smallest LCM that can’t be achieved.
- For finding the minimum possible LCM we can come up with approach: From the observation, It must be noted that the minimum possible LCM will be the smallest number that is not present in A[] and has less than two prime factors. This is because a number with less than two prime factors cannot be the LCM of any non empty set of A[] unless it is in the array A[] itself. This is the key insight that allows the problem to be solved efficiently.
Steps taken to solve the problem:
- Initialize Variables: Create a boolean array let say mp[] and an integer array mp1[] of size MAX (which is set to 10^7 + 7). Also, create an ArrayList V<Integer> to store the prime numbers.
- Implement the Sieve of Eratosthenes: Implement a function Sieve() that generates all prime numbers up to MAX using the Sieve of Eratosthenes algorithm. For each number i from 2 to MAX
- if i is not marked in mp, increment mp1[i] and add i to V. Then, for each multiple j of i, mark j in mp and increment mp1[j]. This results in mp1[i] being the number of distinct prime divisors of i.
- Check Each Integer: For each test case, check each integer i starting from 1. If i is not in A[] (checking using a map defined as seen) and i is a prime number (mp1[i] is 1), then create a variable let say min_lcm and set it equal to i.
- Result: Calculate sum of A[] in a variable let say Sum and then output (Sum/min_lcm).
Code to implement the approach:
C++
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
const int MAX = 10000007;
bool mp[MAX];
int mp1[MAX];
vector< int > v;
void sieve()
{
mp1[1] = 1;
for ( int i = 2; i < MAX; i++)
{
if (!mp[i])
{
mp1[i]++;
v.push_back(i);
for ( int j = i + i; j < MAX; j += i)
{
mp[j] = true ;
mp1[j]++;
}
}
}
}
void Min_LCM( int N, int A[]);
int main()
{
int N = 5;
int A[] = {1, 2, 3, 4, 5};
Min_LCM(N, A);
return 0;
}
void Min_LCM( int N, int A[])
{
sieve();
unordered_map< int , int > seen;
for ( int i = 0; i < N; i++)
{
int x = A[i];
seen[x] = seen[x] + 1;
}
int min_lcm = 0;
for ( int i = 1;; i++)
{
if (seen.find(i) == seen.end() && mp1[i] == 1)
{
min_lcm = i;
break ;
}
}
int sum = 0;
for ( int i = 0; i < N; i++)
{
sum += A[i];
}
cout << sum / min_lcm << endl;
}
|
Java
import java.util.*;
public class Main {
static final int MAX = 10000007 ;
static boolean [] mp = new boolean [MAX];
static int [] mp1 = new int [MAX];
static ArrayList<Integer> v = new ArrayList<>();
public static void main(String[] args)
{
int N = 5 ;
int A[] = { 1 , 2 , 3 , 4 , 5 };
Min_LCM(N, A);
}
public static void Min_LCM( int N, int [] A)
{
sieve();
Map<Integer, Integer> seen = new HashMap<>();
for ( int i = 0 ; i < N; i++) {
int x = A[i];
seen.put(x, seen.getOrDefault(x, 0 ) + 1 );
}
int min_lcm = 0 ;
for ( int i = 1 ;; i++) {
if (!seen.containsKey(i) && mp1[i] == 1 ) {
min_lcm = i;
break ;
}
}
int sum = 0 ;
for ( int x : A) {
sum += x;
}
System.out.println(sum / min_lcm);
}
static void sieve()
{
mp1[ 1 ] = 1 ;
for ( int i = 2 ; i < MAX; i++) {
if (!mp[i]) {
mp1[i]++;
v.add(i);
for ( int j = i + i; j < MAX; j += i) {
mp[j] = true ;
mp1[j]++;
}
}
}
}
}
|
Python3
MAX = 10000007
mp = [ False ] * MAX
mp1 = [ 0 ] * MAX
v = []
def sieve():
mp1[ 1 ] = 1
for i in range ( 2 , MAX ):
if not mp[i]:
mp1[i] + = 1
v.append(i)
for j in range (i + i, MAX , i):
mp[j] = True
mp1[j] + = 1
def min_lcm(N, A):
sieve()
seen = {}
for x in A:
seen[x] = seen.get(x, 0 ) + 1
min_lcm = 0
for i in range ( 1 , MAX ):
if i not in seen and mp1[i] = = 1 :
min_lcm = i
break
_sum = sum (A)
print (_sum / / min_lcm)
if __name__ = = "__main__" :
N = 5
A = [ 1 , 2 , 3 , 4 , 5 ]
min_lcm(N, A)
|
C#
using System;
using System.Collections.Generic;
public class MainClass
{
static readonly int MAX = 10000007;
static bool [] mp = new bool [MAX];
static int [] mp1 = new int [MAX];
static List< int > v = new List< int >();
public static void Main( string [] args)
{
int N = 5;
int [] A = { 1, 2, 3, 4, 5 };
Min_LCM(N, A);
}
public static void Min_LCM( int N, int [] A)
{
Sieve();
Dictionary< int , int > seen = new Dictionary< int , int >();
for ( int i = 0; i < N; i++)
{
int x = A[i];
seen[x] = seen.GetValueOrDefault(x, 0) + 1;
}
int min_lcm = 0;
for ( int i = 1; ; i++)
{
if (!seen.ContainsKey(i) && mp1[i] == 1)
{
min_lcm = i;
break ;
}
}
int sum = 0;
foreach ( int x in A)
{
sum += x;
}
Console.WriteLine(sum / min_lcm);
}
static void Sieve()
{
mp1[1] = 1;
for ( int i = 2; i < MAX; i++)
{
if (!mp[i])
{
mp1[i]++;
v.Add(i);
for ( int j = i + i; j < MAX; j += i)
{
mp[j] = true ;
mp1[j]++;
}
}
}
}
}
|
Javascript
const MAX = 10000007;
const mp = Array(MAX).fill( false );
const mp1 = Array(MAX).fill(0);
const v = [];
function main() {
const N = 5;
const A = [1, 2, 3, 4, 5];
Min_LCM(N, A);
}
function Min_LCM(N, A) {
sieve();
const seen = new Map();
for (let i = 0; i < N; i++) {
const x = A[i];
seen.set(x, (seen.get(x) || 0) + 1);
}
let min_lcm = 0;
for (let i = 1; ; i++) {
if (!seen.has(i) && mp1[i] === 1) {
min_lcm = i;
break ;
}
}
const sum = A.reduce((acc, x) => acc + x, 0);
console.log(Math.floor(sum / min_lcm));
}
function sieve() {
mp1[1] = 1;
for (let i = 2; i < MAX; i++) {
if (!mp[i]) {
mp1[i]++;
v.push(i);
for (let j = i + i; j < MAX; j += i) {
mp[j] = true ;
mp1[j]++;
}
}
}
}
main();
|
Time Complexity: O(N*logN)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...