Open In App

Find the maximum possible value for the given periodic function

Last Updated : 12 Apr, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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)

  • We can observe that the given function is a periodic function. This can be proved by:

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)  

  • Hence, we can conclude that 0 ? x ? B. However, if x = B, f(x) = 0. So, we exclude it and get 0 ? x ? B-1.
  • However, we must also consider the condition x ? N. Since floor(x) is a monotonically non-decreasing function, we must incorporate the best of both ranges.
  • Hence, the maximum value of f(x) is obtained when x = min(B – 1, N).

Below is the implementation of the above approach:

C++




// 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




// 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




# 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#




// 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




// 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:

C++




#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




// 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));
}
}


Python3




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




// 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));


C#




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.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads