Open In App

Find the maximum possible value for the given periodic function

Given three numbers A, B, and N, the task is to find the maximum possible value of floor(A * x / B) – A * floor(x / b) where x is a non-negative integer less than or equal to N. Here floor(T) = denotes the greatest integer not greater than the real number T (G.I.F function). 
Constraints: 1 ? A ? 106, 1 ? B ? 1012, 1 ? N ? 1012. All values in input are integers.

Input: A = 5, B = 7, N = 4 
Output:
Explanation: 
The maximum value is obtained for the value x = 3. On substituting this value in the equation: 
floor((5 * 3)/7) – (5 * floor(3 / 7)) = floor(2.1) – 0 = 2.

Input: A = 11, B = 10, N = 9 
Output: 9  

Naive Approach: The naive approach for this problem is to consider all the possible numbers from 1 to N and compute the maximum possible value. 

Time Complexity: O(N). 

Efficient Approach: The idea is to make an observation on the function f(x) = floor(A * x / B) – A * floor(x / B)

f(x + B) = floor(A * (x + B)/B) – A * floor((x + B)/B) 
=> f(x + B) = floor((A * x / B) + A) – A * floor((x /B) + 1)
By floor-function property, floor(x + Integer) = Integer + floor(x). 
=> f(x + B) = floor(A * x / B) – A * floor(x / B) = f(x)  

Below is the implementation of the above approach:




// C++ Program to find the maximum
// possible value for the given function
 
#include <iostream>
using namespace std;
 
// Function to return the maximum
// value of f(x)
int floorMax(int A, int B, int N)
{
    int x = min(B - 1, N);
 
    return (A * x) / B;
}
 
// Driver code
int main()
{
    int A = 11, B = 10, N = 9;
 
    cout << floorMax(A, B, N);
    return 0;
}




// Java program to find the maximum
// possible value for the given function
class GFG{
     
// Function to return the maximum
// value of f(x)
public static int floorMax(int A, int B, int N)
{
    int x = Math.min(B - 1, N);
 
    return (A * x) / B;
}
 
// Driver Code
public static void main(String[] args)
{
    int A = 11, B = 10, N = 9;
     
    System.out.println(floorMax(A, B, N));
}
}
 
// This code is contributed by divyeshrabadiya07




# Python3 program to find the maximum
# possible value for the given function
  
# Function to return the maximum
# value of f(x)
def floorMax(A, B, N):
     
    x = min(B - 1, N)
  
    return (A * x) // B
  
# Driver code
A = 11
B = 10
N = 9
  
print(floorMax(A, B, N))
 
# This code is contributed by code_hunt




// C# program to find the maximum
// possible value for the given function        
using System;
using System.Collections.Generic;
 
class GFG{        
             
// Function to return the maximum
// value of f(x)
static int floorMax(int A, int B, int N)
{
    int x = Math.Min(B - 1, N);
 
    return (A * x) / B;
}    
         
// Driver Code        
public static void Main (string[] args)
{        
    int A = 11, B = 10, N = 9;
 
    Console.Write(floorMax(A, B, N));
}        
}
 
// This code is contributed by rutvik_56




// Javascript program to find the maximum
// possible value for the given function
 
// Function to return the maximum
// value of f(x)
function floorMax(A, B, N) {
    let x = Math.min(B - 1, N);
 
    return Math.floor((A * x) / B);
}
 
// Driver code
let A = 11,
    B = 10,
    N = 9;
console.log(floorMax(A, B, N));
//This code is contributed by sarojmcy2e

Output: 
9

 

Time Complexity: O(1)

Space Complexity: O(1) as no extra space has been used.
 

New Approach:- Here Another approach to solve this problem is by using the fact that the function is piecewise constant. We can divide the range [0, N] into intervals of length B and compute the value of the function on each interval separately.

Let’s consider an interval [k * B, (k + 1) * B), where 0 ? k ? ?N/B?. The function is constant on this interval and equal to floor(A * x / B) – A * floor(x / B), where x belongs to this interval. We can compute the maximum value of the function on this interval by evaluating it at the endpoints of the interval and taking the maximum.

Let f(k) be the maximum value of the function on the interval [k * B, (k + 1) * B). Then we have:

f(k) = max{floor(A * k / B) – A * floor(k / B), floor(A * (k + 1) / B) – A * floor((k + 1) / B)}

The maximum value of the function on the range [0, N] is the maximum of f(k) over all k.

Steps:- 

  1. Define a function floorMax that takes three integers A, B, and N as input and returns an integer as output.
  2. Initialize a variable maxVal to 0 to store the maximum value of the function.
  3. Loop from k = 0 to k = floor(N/B), where k is an integer variable.
  4. For each k, calculate the values of x1 and x2 using the following formulas: x1 = k * B
    x2 = min((k + 1) * B – 1, N)
    Here, x1 is the lower bound of the interval and x2 is the upper bound of the interval.
  5. Calculate the values of the function f(x) for the intervals [x1, x2] using the following formulas:  val1 = (A * x1) / B – A * (x1 / B)
    val2 = (A * x2) / B – A * (x2 / B)
  6. Determine the maximum value of the function on the current interval using the following formula:  maxValOnInterval = max(val1, val2)
  7. Determine the overall maximum value of the function using the following formula: maxVal = max(maxVal, maxValOnInterval)
  8. Return the maximum value of the function f(x).
  9. In the main function, initialize the values of A, B, and N.
  10. Call the function floorMax with these values and print the result.

Here’s the implementation of this approach in Java:




#include <iostream>
using namespace std;
 
// Function to return the maximum
// value of f(x)
int floorMax(int A, int B, int N) {
    int maxVal = 0;
    for (int k = 0; k <= N / B; k++) {
        int x1 = k * B;
        int x2 = min((k + 1) * B - 1, N);
        int val1 = (A * x1) / B - A * (x1 / B);
        int val2 = (A * x2) / B - A * (x2 / B);
        int maxValOnInterval = max(val1, val2);
        maxVal = max(maxVal, maxValOnInterval);
    }
    return maxVal;
}
 
// Driver Code
int main() {
    int A = 11, B = 10, N = 9;
    cout << floorMax(A, B, N) << endl;
    return 0;
}




// Java program to find the maximum
// possible value for the given function
class GFG {
  // Function to return the maximum
// value of f(x)
public static int floorMax(int A, int B, int N) {
    int maxVal = 0;
    for (int k = 0; k <= N / B; k++) {
        int x1 = k * B;
        int x2 = Math.min((k + 1) * B - 1, N);
        int val1 = (A * x1) / B - A * (x1 / B);
        int val2 = (A * x2) / B - A * (x2 / B);
        int maxValOnInterval = Math.max(val1, val2);
        maxVal = Math.max(maxVal, maxValOnInterval);
    }
    return maxVal;
}
 
// Driver Code
public static void main(String[] args) {
    int A = 11, B = 10, N = 9;
    System.out.println(floorMax(A, B, N));
}
}




def floorMax(A: int, B: int, N: int) -> int:
   
    # Initialize maxVal to 0
    maxVal = 0
     
    # Iterate over k from 0 to N/B
    for k in range(N // B + 1):
       
        # Calculate x1 and x2
        x1 = k * B
        x2 = min((k + 1) * B - 1, N)
         
        # Calculate val1 and val2
        val1 = (A * x1) // B - A * (x1 // B)
        val2 = (A * x2) // B - A * (x2 // B)
         
        # Calculate maxValOnInterval and update maxVal
        maxValOnInterval = max(val1, val2)
        maxVal = max(maxVal, maxValOnInterval)
         
    # Return maxVal
    return maxVal
 
# Set A, B and N to given values
A = 11
B = 10
N = 9
 
# Call floorMax function with given values and print the result
print(floorMax(A, B, N))




// JavaScript program to find the maximum
// possible value for the given function
 
// Function to return the maximum
// value of f(x)
function floorMax(A, B, N) {
let maxVal = 0;
for (let k = 0; k <= Math.floor(N / B); k++) {
let x1 = k * B;
let x2 = Math.min((k + 1) * B - 1, N);
let val1 = Math.floor((A * x1) / B) - A * Math.floor(x1 / B);
let val2 = Math.floor((A * x2) / B) - A * Math.floor(x2 / B);
let maxValOnInterval = Math.max(val1, val2);
maxVal = Math.max(maxVal, maxValOnInterval);
}
return maxVal;
}
 
// Driver Code
let A = 11, B = 10, N = 9;
console.log(floorMax(A, B, N));




using System;
 
public class Program
{
// Function to return the maximum value of f(x)
public static int FloorMax(int A, int B, int N)
{
int maxVal = 0;
for (int k = 0; k <= N / B; k++)
{
int x1 = k * B;
int x2 = Math.Min((k + 1) * B - 1, N);
int val1 = (A * x1) / B - A * (x1 / B);
int val2 = (A * x2) / B - A * (x2 / B);
int maxValOnInterval = Math.Max(val1, val2);
maxVal = Math.Max(maxVal, maxValOnInterval);
}
return maxVal;
}
  // Driver Code
public static void Main()
{
    int A = 11, B = 10, N = 9;
    Console.WriteLine(FloorMax(A, B, N));
}
}

Output:-

9

Time Complexity:- Time complexity of the given Java program is O(N/B), since the for loop runs N/B times. Inside the loop, the time complexity of each operation is O(1). Therefore, the overall time complexity is O(N/B).

Auxiliary Space:- The space complexity of the program is O(1), since only a constant amount of extra memory is required for the variables used in the program. Hence, the space complexity of the program is constant.


Article Tags :