Related Articles

Related Articles

Maximize the value of F(N) = max( N, F(N /2) + F(N / 3) + F(N / 4)) for any given integer
  • Difficulty Level : Expert
  • Last Updated : 02 Nov, 2020

Given an integer N, the task is to find the maximum value of function F(n) given by F(N) = max(N, F(N /2) + F(N / 3) + F(N / 4)).

Examples:

Input: N = 3
Output: 3
Explanation:
F(3) = max(3, F(1) + F(1) + F(0)) as F(0) = 0 and F(1) = 1
F(3) = max(3, 1 + 1+ 0)
F(3) = max(3, 2)
Hence, the maximum value of F(3) is 3.

Input: N = 12
Output:13
Explanation:
F(12) = max(12, F(6) + F(4) + F(3))
F(6) = max(6, F(3) + F(2) + F(1)) 
F(3) = max(3, F(1) + F(1) + F(0)) as F(0) = 0 and F(1) = 1
F(3) = max(3, 1 + 1+ 0)
F(3) = max(3, 2) = 3
F(2) = max(2, F(1) + F(0) + F(0)) 
F(2) = max(2,1 + 0 + 0) = 2
F(4) = max(4, F(2) + F(1) + F(1)) 
F(4) = max(4, 2 + 1 + 1) = 4 
F(6) = max(6, 3 + 2 + 1) = 6
Now, F(12) = max(12, 6 + 4 + 3)
F(12) = max(12, 13)
Hence, the maximum value of F(12) is 13.

Naive Approach: The simplest approach is to use recursion to calculate the value of F(N). In each step, call three recursive calls for each of the value N/2, N/3, and N/4, and then each recursive call returns the value of the maximum of N and the sum of values returned by these recursive calls. After all the recursive call ends print the value as the result.



Time Complexity: O(3N)
Auxiliary Space: O(1)

Dynamic Programming using Bottom-Down Approach: The recursive calls in the above can also be reduced using an auxiliary array dp[] and calculate the value of each state in the bottom-up approach. Below are the steps:

  • Create an auxiliary array dp[] of size N.
  • Initialize the state 0 and 1 as dp[0] = 0 and dp[1] = 1.
  • Traverse the array dp[] over the range [2, N] and update each state as:

dp[i] = max(i, dp[i/2] + dp[i/3] + dp[i/4])

  • Print the value of dp[N] after the above steps as the result.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to build the auxiliary DP
// array from the start
void build(int dp[], int N)
{
    // Base Case
    dp[0] = 0;
    dp[1] = 1;
 
// Iterate over the range
    for (int i = 2; i <= N; i++) {
     
    // Update each state
        dp[i] = max(i, dp[i / 2]
                    + dp[i / 3]
                    + dp[i / 4]);
    }
}
 
// Function to find the maximum value of
// F(n) = max(n, F[n/2] + F[n/3] + F[n/4])
int maxValue(int N)
{
    // Auxuliary DP array
    int dp[N + 1];
 
    // Function call to build DP array
    build(dp, N);
 
    // Print the answer
    cout << dp[N];
}
 
// Driver Code
int main()
{
    // Given N
    int N = 12;
 
    // Function Call
    maxValue(N);
 
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
import java.util.*;
 
class GFG{
       
// Function to build the auxiliary DP
// array from the start
static void build(int dp[], int N)
{
     
    // Base Case
    dp[0] = 0;
    dp[1] = 1;
     
    // Iterate over the range
    for(int i = 2; i <= N; i++)
    {
         
        // Update each state
        dp[i] = Math.max(i, dp[i / 2] +
                            dp[i / 3] +
                            dp[i / 4]);
    }
}
  
// Function to find the maximum value of
// F(n) = max(n, F[n/2] + F[n/3] + F[n/4])
static void maxValue(int N)
{
     
    // Auxuliary DP array
    int dp[] = new int[N + 1];
  
    // Function call to build DP array
    build(dp, N);
  
    // Print the answer
    System.out.println(dp[N]);
}
   
// Driver code
public static void main(String[] args)
{
     
    // Given N
    int N = 12;
  
    // Function Call
    maxValue(N);
}
}
  
// This code is contributed by code_hunt

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for the above approach
 
# Function to build the auxiliary DP
# array from the start
def build(dp, N):
     
    # Base Case
    dp[0] = 0
    dp[1] = 1
     
    # Iterate over the range
    for i in range(2, N + 1):
         
        # Update each state
        dp[i] = max(i, dp[i // 2] +
                    dp[i // 3] +
                    dp[i // 4])
 
# Function to find the maximum value of
# F(n) = max(n, F[n/2] + F[n/3] + F[n/4])
def maxValue(N):
     
    # Auxuliary DP array
    dp = [0] * (N + 1)
 
    # Function call to build DP array
    build(dp, N)
 
    # Print the answer
    print(dp[N], end = "")
 
# Driver Code
if __name__ == '__main__':
     
    # Given N
    N = 12
     
    # Function Call
    maxValue(N)
 
# This code is contributed by mohit kumar 29

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the
// above approach
using System;
class GFG{
       
// Function to build the
// auxiliary DP array
// from the start
static void build(int []dp,
                  int N)
{   
  // Base Case
  dp[0] = 0;
  dp[1] = 1;
 
  // Iterate over the range
  for(int i = 2; i <= N; i++)
  {
    // Update each state
    dp[i] = Math.Max(i, dp[i / 2] +
                     dp[i / 3] +
                     dp[i / 4]);
  }
}
  
// Function to find the
// maximum value of F(n) =
// max(n, F[n/2] + F[n/3] + F[n/4])
static void maxValue(int N)
{   
  // Auxuliary DP array
  int []dp = new int[N + 1];
 
  // Function call to
  // build DP array
  build(dp, N);
 
  // Print the answer
  Console.WriteLine(dp[N]);
}
   
// Driver code
public static void Main(String[] args)
{   
  // Given N
  int N = 12;
 
  // Function Call
  maxValue(N);
}
}
 
// This code is contributed by Rajput-Ji

chevron_right


Output

13







Time Complexity: O(N)
Space Complexity: O(N)

Dynamic Programming using Top-Down Approach: As in the above approach there are many Overlapping Subproblems for each recursive call. Therefore, to optimize the above approach, the idea is to use the auxiliary space map to store the value calculated in each recursive call and return the recurring stored state. Below are the steps:

  • Initialize a map Map to store the value calculated at each recursive call.
  • Base Case: If the value of N is 0 or 1 then the result is 0 and 1 respectively. Also if there is any previously calculated state then return that value as:

>Base Case:
if(N <= 1) {
     return N;
}
Memoized State:
if(Map.find(N) != Map.end()) {
     return Map[N];
}

  • Recursive Call: If the base case is not met, then find the value of the current state by recursively calling for each state as:

result = max(N, recursive_function(N/2) + recursive_function(N/3) + recursive_function(N/4))

  • Return Statement: At each recursive call(except the base case), store the current state calculated in the above step in the map and return the value calculated as the result for the current state.

Map[N] = result;
return result;

  • After the above steps, print the value return to the end of all the recursive calls.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Map used for memoization
map<int, int> mp;
 
// Function to find maximum value
// of the given recurrence relation
int maxValue(int N)
{
    // Base Case
    if (N <= 1)
        return N;
 
    // If previously computed
    if (mp[N] != 0)
        return mp[N];
 
    // Computing value of function
    // when its not already computed
    int ans = max(N, maxValue(N / 2)
                + maxValue(N / 3)
                + maxValue(N / 4));
 
    // Storing value for further
    // computation reduction
    mp[N] = ans;
 
    return ans;
}
 
// Utility function to find maximum value
// of the given recurrence relation
void maxValueUtil(int N)
{
    // Stores final result
    int result = maxValue(N);
 
    // Print the result
    cout << result;
}
 
// Drive Code
int main()
{
    // Given N
    int N = 12;
 
    // Function Call
    maxValueUtil(N);
 
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
import java.util.*;
import java.lang.*;
 
class GFG{
     
// Map used for memoization
static Map<Integer, Integer> mp = new HashMap<>();
  
// Function to find maximum value
// of the given recurrence relation
static int maxValue(int N)
{
     
    // Base Case
    if (N <= 1)
        return N;
  
    // If previously computed
    if (mp.containsKey(N))
        return mp.get(N);
  
    // Computing value of function
    // when its not already computed
    int ans = Math.max(N, maxValue(N / 2) +
                          maxValue(N / 3) +
                          maxValue(N / 4));
  
    // Storing value for further
    // computation reduction
    mp.put(N, ans);
  
    return ans;
}
  
// Utility function to find maximum value
// of the given recurrence relation
static void maxValueUtil(int N)
{
     
    // Stores final result
    int result = maxValue(N);
  
    // Print the result
    System.out.print(result);
}
 
// Driver code
public static void main (String[] args)
{
 
    // Given N
    int N = 12;
     
    // Function Call
    maxValueUtil(N);
}
}
 
// This code is contributed by offbeat

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for the above approach
 
# Map used for memoization
mp = {}
 
# Function to find maximum value
# of the given recurrence relation
def maxValue(N):
   
    # Base Case
    if (N <= 1):
        return N
 
    # If previously computed
    if (N in mp):
        return mp[N]
 
    # Computing value of function
    # when its not already computed
    ans = (max(N, maxValue(N // 2) +
                  maxValue(N // 3) +
                  maxValue(N // 4)))
 
    # Storing value for further
    # computation reduction
    if(N in mp):
      mp[N] = ans
    else:
      mp[N] = mp.get(N, 0) + ans
 
    return ans
 
# Utility function to find maximum value
# of the given recurrence relation
def maxValueUtil(N):
   
    # Stores final result
    result = maxValue(N)
 
    # Print the result
    print(result)
 
# Drive Code
if __name__ == '__main__':
   
    # Given N
    N = 12
 
    # Function Call
    maxValueUtil(N)
 
# This code is contributed by SURENDRA_GANGWAR

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program for the
// above approach
using System;
using System.Collections.Generic;
class GFG{
     
// Map used for memoization
static Dictionary<int,
                  int> mp = new Dictionary<int,
                                           int>();
   
// Function to find maximum value
// of the given recurrence relation
static int maxValue(int N)
{   
  // Base Case
  if (N <= 1)
    return N;
 
  // If previously computed
  if (mp.ContainsKey(N))
    return mp[N];
 
  // Computing value of function
  // when its not already computed
  int ans = Math.Max(N, maxValue(N / 2) +
                     maxValue(N / 3) +
                     maxValue(N / 4));
 
  // Storing value for further
  // computation reduction
  mp.Add(N, ans);
 
  return ans;
}
  
// Utility function to find
// maximum value of the given
// recurrence relation
static void maxValueUtil(int N)
{   
  // Stores readonly result
  int result = maxValue(N);
 
  // Print the result
  Console.Write(result);
}
 
// Driver code
public static void Main(String[] args)
{
  // Given N
  int N = 12;
 
  // Function Call
  maxValueUtil(N);
}
}
 
// This code is contributed by Princi Singh

chevron_right


Output

13







Time Complexity: O(log N)
Auxiliary Space: O(log N)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up
Recommended Articles
Page :