Find the maximum number of composite summands of a number
Last Updated :
09 Jun, 2022
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:
- Only 4, 6, 9 occurs in optimal splittings.
- It is not beneficial to use 6 or 9 more than once because 6 + 6 = 4 + 4 + 4, 9 + 9 = 6 + 6 + 6.
- 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++
#include <bits/stdc++.h>
using namespace std;
const int maxn = 16;
vector< int > precompute()
{
vector< int > dp(maxn, -1);
dp[0] = 0;
for ( int i = 1; i < maxn; ++i) {
for ( auto j : vector< int >{ 4, 6, 9 }) {
if (i >= j && dp[i - j] != -1) {
dp[i] = max(dp[i], dp[i - j] + 1);
}
}
}
return dp;
}
int Maximum_Summands(vector< int > dp, int n)
{
if (n < maxn)
return dp[n];
else {
int t = (n - maxn) / 4 + 1;
return t + dp[n - 4 * t];
}
}
int main()
{
int n = 12;
vector< int > dp = precompute();
cout << Maximum_Summands(dp, n) << endl;
return 0;
}
|
Java
class GFG
{
static int maxn = 16 ;
static int [] precompute()
{
int dp[] = new int [maxn], arr[]={ 4 , 6 , 9 };
for ( int i = 0 ; i < maxn; i++)dp[i] = - 1 ;
dp[ 0 ] = 0 ;
for ( int i = 1 ; i < maxn; ++i)
{
for ( int k = 0 ; k < 3 ; k++)
{
int j = arr[k];
if (i >= j && dp[i - j] != - 1 )
{
dp[i] = Math.max(dp[i], dp[i - j] + 1 );
}
}
}
return dp;
}
static int Maximum_Summands( int [] dp, int n)
{
if (n < maxn)
return dp[n];
else {
int t = (n - maxn) / 4 + 1 ;
return t + dp[n - 4 * t];
}
}
public static void main(String args[])
{
int n = 12 ;
int [] dp = precompute();
System.out.println(Maximum_Summands(dp, n));
}
}
|
Python3
global maxn
maxn = 16
def precompute():
dp = [ - 1 for i in range (maxn)]
dp[ 0 ] = 0
v = [ 4 , 6 , 9 ]
for i in range ( 1 , maxn, 1 ):
for k in range ( 3 ):
j = v[k]
if (i > = j and dp[i - j] ! = - 1 ):
dp[i] = max (dp[i], dp[i - j] + 1 )
return dp
def Maximum_Summands(dp, n):
if (n < maxn):
return dp[n]
else :
t = int ((n - maxn) / 4 ) + 1
return t + dp[n - 4 * t]
if __name__ = = '__main__' :
n = 12
dp = precompute()
print (Maximum_Summands(dp, n))
|
C#
using System;
using System.Collections;
class GFG
{
static int maxn = 16;
static int [] dp = new int [maxn + 1];
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)
{
foreach ( int j in vec)
{
if (i >= j && dp[i - j] != -1)
{
dp[i] = Math.Max(dp[i], dp[i - j] + 1);
}
}
}
}
static int Maximum_Summands( int n)
{
if (n < maxn)
return dp[n];
else
{
int t = (n - maxn) / 4 + 1;
return t + dp[n - 4 * t];
}
}
static void Main()
{
int n = 12;
precompute();
Console.WriteLine(Maximum_Summands(n));
}
}
|
PHP
<?php
$maxn = 16;
function precompute()
{
$dp = array_fill (0, $GLOBALS [ 'maxn' ], -1);
$dp [0] = 0;
$v = array (4, 6, 9);
for ( $i = 1;
$i < $GLOBALS [ 'maxn' ]; ++ $i )
{
for ( $k = 0; $k <3 ; $k ++)
{
$j = $v [ $k ];
if ( $i >= $j && $dp [ $i - $j ] != -1)
{
$dp [ $i ] = max( $dp [ $i ],
$dp [ $i - $j ] + 1);
}
}
}
return $dp ;
}
function Maximum_Summands( $dp , $n )
{
if ( $n < $GLOBALS [ 'maxn' ])
return $dp [ $n ];
else
{
$t = ( $n - $GLOBALS [ 'maxn' ]) / 4 + 1;
return $t + $dp [ $n - 4 * $t ];
}
}
$n = 12;
$dp = precompute();
echo Maximum_Summands( $dp , $n );
?>
|
Javascript
<script>
let maxn = 16;
function precompute()
{
let dp = new Array(maxn);
let arr = [ 4, 6, 9 ];
for (let i = 0; i < maxn; i++)
dp[i] = -1;
dp[0] = 0;
for (let i = 1; i < maxn; ++i)
{
for (let k = 0; k < 3; k++)
{
let j = arr[k];
if (i >= j && dp[i - j] != -1)
{
dp[i] = Math.max(dp[i], dp[i - j] + 1);
}
}
}
return dp;
}
function Maximum_Summands(dp, n)
{
if (n < maxn)
return dp[n];
else {
let t = parseInt((n - maxn) / 4, 10) + 1;
return t + dp[n - 4 * t];
}
}
let n = 12;
let dp = precompute();
document.write(Maximum_Summands(dp, n));
</script>
|
Time Complexity: O(maxn)
Auxiliary Space: O(maxn)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...