Find the maximum number of composite summands of a number

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

Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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 using namespace std;    const int maxn = 16;    // Function to generate the dp array vector precompute() {     vector dp(maxn, -1);     dp[0] = 0;        for (int i = 1; i < maxn; ++i) {            // combination of three integers         for (auto j : vector{ 4, 6, 9 }) {                // take the maxium 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 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 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 };    // initilize 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 maxium 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 maxium 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 maxium 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

 = \$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 ?>

Output:

3

My Personal Notes arrow_drop_up

pawanasipugmailcom

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.