Find the maximum possible value for the given periodic function
Last Updated :
12 Apr, 2023
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: 2
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++
#include <iostream>
using namespace std;
int floorMax( int A, int B, int N)
{
int x = min(B - 1, N);
return (A * x) / B;
}
int main()
{
int A = 11, B = 10, N = 9;
cout << floorMax(A, B, N);
return 0;
}
|
Java
class GFG{
public static int floorMax( int A, int B, int N)
{
int x = Math.min(B - 1 , N);
return (A * x) / B;
}
public static void main(String[] args)
{
int A = 11 , B = 10 , N = 9 ;
System.out.println(floorMax(A, B, N));
}
}
|
Python3
def floorMax(A, B, N):
x = min (B - 1 , N)
return (A * x) / / B
A = 11
B = 10
N = 9
print (floorMax(A, B, N))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int floorMax( int A, int B, int N)
{
int x = Math.Min(B - 1, N);
return (A * x) / B;
}
public static void Main ( string [] args)
{
int A = 11, B = 10, N = 9;
Console.Write(floorMax(A, B, N));
}
}
|
Javascript
function floorMax(A, B, N) {
let x = Math.min(B - 1, N);
return Math.floor((A * x) / B);
}
let A = 11,
B = 10,
N = 9;
console.log(floorMax(A, B, N));
|
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:-
- Define a function floorMax that takes three integers A, B, and N as input and returns an integer as output.
- Initialize a variable maxVal to 0 to store the maximum value of the function.
- Loop from k = 0 to k = floor(N/B), where k is an integer variable.
- 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.
- 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)
- Determine the maximum value of the function on the current interval using the following formula: maxValOnInterval = max(val1, val2)
- Determine the overall maximum value of the function using the following formula: maxVal = max(maxVal, maxValOnInterval)
- Return the maximum value of the function f(x).
- In the main function, initialize the values of A, B, and N.
- 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;
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;
}
int main() {
int A = 11, B = 10, N = 9;
cout << floorMax(A, B, N) << endl;
return 0;
}
|
Java
class GFG {
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;
}
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 :
maxVal = 0
for k in range (N / / B + 1 ):
x1 = k * B
x2 = min ((k + 1 ) * B - 1 , N)
val1 = (A * x1) / / B - A * (x1 / / B)
val2 = (A * x2) / / B - A * (x2 / / B)
maxValOnInterval = max (val1, val2)
maxVal = max (maxVal, maxValOnInterval)
return maxVal
A = 11
B = 10
N = 9
print (floorMax(A, B, N))
|
Javascript
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;
}
let A = 11, B = 10, N = 9;
console.log(floorMax(A, B, N));
|
C#
using System;
public class Program
{
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;
}
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
Share your thoughts in the comments
Please Login to comment...