Open In App

Find the maximum number of composite summands of a number

Last Updated : 09 Jun, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given an integer N(1<=N<=10^9). The task is to represent N as a sum of the maximum possible number of composite summands and print this maximum number, or print -1, if there are no such splittings. There can be multiple queries

Examples: 

Input : 12
Output : 3
Explanation : 12 can be written has 4 + 4 + 4 or 6 + 6 or 8 + 4
But, 4 + 4 + 4 has maximum number of summands.

Input : 7
Output : -1

Approach : Note that minimal composite number is equal to 4. So it is quite logical that there will be a lot of 4 in a splitting of big numbers. Let’s write for small numbers (1<=M<=N) dpN be the number of composite summands in splitting of N.
Let’s find an answer for all numbers from 1 to 15. Several observations: 

  1. Only 4, 6, 9 occurs in optimal splittings.
  2. It is not beneficial to use 6 or 9 more than once because 6 + 6 = 4 + 4 + 4, 9 + 9 = 6 + 6 + 6.
  3. 12, 13, 14, 15 have valid splittings.

Let’s prove that all numbers that are greater than 15 will have 4 in optimal splitting. Let’s guess that it is incorrect. If the minimal number in splitting is neither 4 nor 6 nor 9 then this number will have some non-trivial splitting by induction.
If this number either 6 or 9 and we will decrease query by this number then we will sooner or later get some small number (which is less or equal than 15). There is no splitting of small numbers or it contains 4 in splitting (and it contradicts with minimality of the first number) or it contains 6 and 9. So we have contradiction in all cases.
We can subtract 4 from any big query and our solution is correct.
If our query n is small number let’s print dpn. Else let’s find minimal number k such that n – 4·k is a small number. Then print k + dpn – 4·k.

Below is the implementation of the above approach:  

C++




// C++ implementation of the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
const int maxn = 16;
 
// Function to generate the dp array
vector<int> precompute()
{
    vector<int> dp(maxn, -1);
    dp[0] = 0;
 
    for (int i = 1; i < maxn; ++i) {
 
        // combination of three integers
        for (auto j : vector<int>{ 4, 6, 9 }) {
 
            // take the maximum number of summands
            if (i >= j && dp[i - j] != -1) {
                dp[i] = max(dp[i], dp[i - j] + 1);
            }
        }
    }
 
    return dp;
}
 
// Function to find the maximum number of summands
int Maximum_Summands(vector<int> dp, int n)
{
    // If n is a smaller number, less than 16
    // return dp[n]
    if (n < maxn)
        return dp[n];
 
    else {
 
        // Else, find a minimal number t
        // as explained in solution
        int t = (n - maxn) / 4 + 1;
        return t + dp[n - 4 * t];
    }
}
 
// Driver code
int main()
{
    int n = 12;
 
    // Generate dp array
    vector<int> dp = precompute();
 
    cout << Maximum_Summands(dp, n) << endl;
 
    return 0;
}


Java




// Java implementation of the above approach
class GFG
{
 
static int maxn = 16;
 
// Function to generate the dp array
static int[] precompute()
{
int dp[] = new int[maxn], arr[]={ 4, 6, 9 };
 
// initialize
for(int i = 0; i < maxn; i++)dp[i] = -1;
 
dp[0] = 0;
 
for (int i = 1; i < maxn; ++i)
{
 
    // combination of three integers
    for (int k = 0; k < 3; k++)
    {
        int j = arr[k];
 
        // take the maximum number of summands
        if (i >= j && dp[i - j] != -1)
        {
            dp[i] = Math.max(dp[i], dp[i - j] + 1);
        }
    }
}
 
return dp;
}
 
// Function to find the maximum number of summands
static int Maximum_Summands(int[] dp, int n)
{
// If n is a smaller number, less than 16
// return dp[n]
if (n < maxn)
    return dp[n];
 
else {
 
    // Else, find a minimal number t
    // as explained in solution
    int t = (n - maxn) / 4 + 1;
    return t + dp[n - 4 * t];
}
}
 
// Driver code
public static void main(String args[])
{
    int n = 12;
 
    // Generate dp array
    int[] dp = precompute();
 
    System.out.println(Maximum_Summands(dp, n));
}
}
 
// This code is contributed by Arnab Kundu


Python3




# Python 3 implementation of the above approach
global maxn
maxn = 16
 
# Function to generate the dp array
def precompute():
    dp = [-1 for i in range(maxn)]
    dp[0] = 0
 
    v = [4, 6, 9]
 
    for i in range(1, maxn, 1):
         
        # combination of three integers
        for k in range(3):
            j = v[k]
             
            # take the maximum number of summands
            if (i >= j and dp[i - j] != -1):
                dp[i] = max(dp[i], dp[i - j] + 1)
 
    return dp
 
# Function to find the maximum number of summands
def Maximum_Summands(dp, n):
     
    # If n is a smaller number,
    # less than 16, return dp[n]
    if (n < maxn):
        return dp[n]
 
    else:
         
        # Else, find a minimal number t
        # as explained in solution
        t = int((n - maxn) / 4)+ 1
        return t + dp[n - 4 * t]
 
# Driver code
if __name__ == '__main__':
    n = 12
 
    # Generate dp array
    dp = precompute()
 
    print(Maximum_Summands(dp, n))
     
# This code is contributed by
# Surendra_Gangwar


C#




// C# implementation of the above approach
using System;
using System.Collections;
 
class GFG
{
     
static int maxn = 16;
static int[] dp = new int[maxn + 1];
 
// Function to generate the dp array
static void precompute()
{
    for(int i = 0; i <= maxn; i++)
    dp[i] = -1;
    dp[0] = 0;
    int[] vec = { 4, 6, 9 };
    for (int i = 1; i < maxn; ++i)
    {
 
        // combination of three integers
        foreach (int j in vec)
        {
 
            // take the maximum number of summands
            if (i >= j && dp[i - j] != -1)
            {
                dp[i] = Math.Max(dp[i], dp[i - j] + 1);
            }
        }
    }
 
}
 
// Function to find the maximum number of summands
static int Maximum_Summands(int n)
{
    // If n is a smaller number, less than 16
    // return dp[n]
    if (n < maxn)
        return dp[n];
 
    else
    {
 
        // Else, find a minimal number t
        // as explained in solution
        int t = (n - maxn) / 4 + 1;
        return t + dp[n - 4 * t];
    }
}
 
// Driver code
static void Main()
{
    int n = 12;
 
    // Generate dp array
    precompute();
 
    Console.WriteLine(Maximum_Summands(n));
}
}
 
// This code is contributed by chandan_jnu


PHP




<?php
// PHP implementation of the above approach
$maxn = 16;
 
// Function to generate the dp array
function precompute()
{
    $dp = array_fill(0, $GLOBALS['maxn'], -1);
    $dp[0] = 0;
 
    $v = array(4, 6, 9);
    for ($i = 1;
         $i < $GLOBALS['maxn']; ++$i)
    {
 
        // combination of three integers
        for ($k = 0; $k<3 ;$k++)
        {
            $j = $v[$k];
 
            // take the maximum number of summands
            if ($i >= $j && $dp[$i - $j] != -1)
            {
                $dp[$i] = max($dp[$i],
                              $dp[$i - $j] + 1);
            }
        }
    }
 
    return $dp;
}
 
// Function to find the maximum
// number of summands
function Maximum_Summands($dp, $n)
{
    // If n is a smaller number,
    // less than 16 return dp[n]
    if ($n < $GLOBALS['maxn'])
        return $dp[$n];
 
    else
    {
 
        // Else, find a minimal number t
        // as explained in solution
        $t = ($n - $GLOBALS['maxn']) / 4 + 1;
        return $t + $dp[$n - 4 * $t];
    }
}
 
// Driver code
$n = 12;
 
// Generate dp array
$dp = precompute();
 
echo Maximum_Summands($dp, $n);
 
// This code is contributed by Ryuga
?>


Javascript




<script>
 
    // JavaScript implementation of the above approach
     
    let maxn = 16;
  
    // Function to generate the dp array
    function precompute()
    {
        let dp = new Array(maxn);
        let arr = [ 4, 6, 9 ];
 
        // initialize
        for(let i = 0; i < maxn; i++)
            dp[i] = -1;
 
        dp[0] = 0;
 
        for (let i = 1; i < maxn; ++i)
        {
 
            // combination of three integers
            for (let k = 0; k < 3; k++)
            {
                let j = arr[k];
 
                // take the maximum number of summands
                if (i >= j && dp[i - j] != -1)
                {
                    dp[i] = Math.max(dp[i], dp[i - j] + 1);
                }
            }
        }
 
        return dp;
    }
 
    // Function to find the maximum number of summands
    function Maximum_Summands(dp, n)
    {
        // If n is a smaller number, less than 16
        // return dp[n]
        if (n < maxn)
            return dp[n];
 
        else {
 
            // Else, find a minimal number t
            // as explained in solution
            let t = parseInt((n - maxn) / 4, 10) + 1;
            return t + dp[n - 4 * t];
        }
    }
     
    let n = 12;
  
    // Generate dp array
    let dp = precompute();
  
    document.write(Maximum_Summands(dp, n));
     
</script>


Output: 

3

 

Time Complexity: O(maxn)

Auxiliary Space: O(maxn)



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

Similar Reads