Count possible splits of sum N into K integers such that the minimum is at least P
Given three integers N, P, and K, the task is to find the total number of ways to divide N into K integers having sum N where each integer is ? P.
Examples:
Input: K = 3, N = 8, P = 2
Output: 6
Explanation:
Six possible solutions are: {2, 2, 4}, {2, 3, 3}, {2, 4, 2}, {3, 2, 3}, {3, 3, 2}, {4, 2, 2}
Each of the above integers in all combinations are ? P(= 2) and sum of all the combinations is N(=8).
Input: K = 2, N = 7, P = 2
Output: 4
Explanation:
Four possible solutions are: {4, 3}, {3, 4}, {5, 2}, {2, 5}
Each of the above integers in all combinations are ? P(= 2) and sum of all the combinations is N(= 7).
Naive Approach: The simplest approach is to try all possible combinations of K integers having sum N and check if they satisfy the above conditions or not. There are K positions and in each position, N integers can be placed. Therefore, the total number of combinations to check is NK.
Time Complexity: O(NK)
Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach, the idea is to use the approach discussed in this article and the given above conditions can be written in terms of a linear equation is:
To find the number of solutions for the equation X1 + X2 + X3 + … + XK = N where Xi ? P.
Assume Xi‘ = Xi – P.
Therefore, the equation reduces to:
X1‘ + X2‘ + X3‘ + … + XK‘ = N – K*P
As per the above equations, the given problem reduces to finding total number of ways to split N – K * P into K integers. Print the total number of ways found above as the required answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int binomialCoeff( int n, int k)
{
int C[n + 1][k + 1];
int i, j;
for (i = 0; i <= n; i++) {
for (j = 0; j <= min(i, k); j++) {
if (j == 0 || j == i)
C[i][j] = 1;
else
C[i][j] = C[i - 1][j - 1]
+ C[i - 1][j];
}
}
return C[n][k];
}
int waysToSplitN( int k, int n, int P)
{
int new_N = n - k * P;
return binomialCoeff(new_N + k - 1,
new_N);
}
int main()
{
int K = 3, N = 8, P = 2;
cout << waysToSplitN(K, N, P);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int binomialCoeff( int n, int k)
{
int [][]C = new int [n + 1 ][k + 1 ];
int i, j;
for (i = 0 ; i <= n; i++)
{
for (j = 0 ; j <= Math.min(i, k); j++)
{
if (j == 0 || j == i)
C[i][j] = 1 ;
else
C[i][j] = C[i - 1 ][j - 1 ] +
C[i - 1 ][j];
}
}
return C[n][k];
}
static int waysToSplitN( int k,
int n, int P)
{
int new_N = n - k * P;
return binomialCoeff(new_N + k - 1 ,
new_N);
}
public static void main(String[] args)
{
int K = 3 , N = 8 , P = 2 ;
System.out.print(waysToSplitN(K, N, P));
}
}
|
Python3
def binomialCoeff(n, k):
C = [[ 0 for x in range (k + 1 )]
for y in range (n + 1 )]
for i in range (n + 1 ):
for j in range ( min (i, k) + 1 ):
if (j = = 0 or j = = i):
C[i][j] = 1
else :
C[i][j] = (C[i - 1 ][j - 1 ] +
C[i - 1 ][j])
return C[n][k]
def waysToSplitN(k, n, P):
new_N = n - k * P
return binomialCoeff(new_N + k - 1 ,
new_N)
K = 3
N = 8
P = 2
print (waysToSplitN(K, N, P))
|
C#
using System;
class GFG{
static int binomialCoeff( int n, int k)
{
int [,] C = new int [n + 1, k + 1];
int i, j;
for (i = 0; i <= n; i++)
{
for (j = 0; j <= Math.Min(i, k); j++)
{
if (j == 0 || j == i)
C[i, j] = 1;
else
C[i, j] = C[i - 1, j - 1] +
C[i - 1, j];
}
}
return C[n, k];
}
static int waysToSplitN( int k, int n,
int P)
{
int new_N = n - k * P;
return binomialCoeff(new_N + k - 1,
new_N);
}
public static void Main()
{
int K = 3, N = 8, P = 2;
Console.Write(waysToSplitN(K, N, P));
}
}
|
Javascript
<script>
function binomialCoeff(n, k)
{
let C = new Array(n + 1);
for (let i = 0; i < C.length; i++) {
C[i] = new Array(2);
}
let i, j;
for (i = 0; i <= n; i++)
{
for (j = 0; j <= Math.min(i, k); j++)
{
if (j == 0 || j == i)
C[i][j] = 1;
else
C[i][j] = C[i - 1][j - 1] +
C[i - 1][j];
}
}
return C[n][k];
}
function waysToSplitN(k, n, P)
{
let new_N = n - k * P;
return binomialCoeff(new_N + k - 1,
new_N);
}
let K = 3, N = 8, P = 2;
document.write(waysToSplitN(K, N, P));
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(N2)
Efficient approach : Space optimization
In previous approach the dp[i][j] is depend upon the current and previous row of 2D matrix. So to optimize space we use two vectors curr and prev that keep track of current and previous row of DP.
Implementation Steps:
- Initialize two vectors curr and prev to keep track of only current and previous row of Dp with 0.
- Now iterative over subproblems and get the current computation.
- While iteration initialize curr vector.
- Now compute the current value by the help of prev vector and store that value in curr.
- After every iteration store values of curr vector in prev vector for further iteration.
- At last return the answer stored in curr[k] .
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int binomialCoeff( int n, int k)
{
vector< int > prev(k + 1, 0);
vector< int > curr(k + 1, 0);
for ( int i = 0; i <= n; i++) {
for ( int j = 0; j <= min(i, k); j++) {
if (j == 0 || j == i)
curr[j] = 1;
else
curr[j] = prev[j - 1] + prev[j];
}
prev = curr;
}
return curr[k];
}
int waysToSplitN( int k, int n, int P)
{
int new_N = n - k * P;
return binomialCoeff(new_N + k - 1, new_N);
}
int main()
{
int K = 3, N = 8, P = 2;
cout << waysToSplitN(K, N, P);
return 0;
}
|
Java
import java.util.*;
public class Main {
static int binomialCoeff( int n, int k)
{
int [] prev = new int [k + 1 ];
int [] curr = new int [k + 1 ];
for ( int i = 0 ; i <= n; i++) {
for ( int j = 0 ; j <= Math.min(i, k); j++) {
if (j == 0 || j == i)
curr[j] = 1 ;
else
curr[j] = prev[j - 1 ] + prev[j];
}
prev = curr.clone();
}
return curr[k];
}
static int waysToSplitN( int k, int n, int P)
{
int new_N = n - k * P;
return binomialCoeff(new_N + k - 1 , new_N);
}
public static void main(String[] args)
{
int K = 3 , N = 8 , P = 2 ;
System.out.println(waysToSplitN(K, N, P));
}
}
|
Python3
def binomial_coeff(n, k):
prev = [ 0 ] * (k + 1 )
curr = [ 0 ] * (k + 1 )
for i in range (n + 1 ):
for j in range ( min (i, k), - 1 , - 1 ):
if j = = 0 or j = = i:
curr[j] = 1
else :
curr[j] = prev[j - 1 ] + prev[j]
prev = curr.copy()
return curr[k]
def ways_to_split_n(k, n, p):
new_n = n - k * p
return binomial_coeff(new_n + k - 1 , new_n)
if __name__ = = '__main__' :
k = 3
n = 8
p = 2
print (ways_to_split_n(k, n, p))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
public static int binomialCoeff( int n, int k)
{
List< int > prev = new List< int >();
List< int > curr = new List< int >();
for ( int i = 0; i <= k; i++)
prev.Add(0);
for ( int i = 0; i <= k; i++)
curr.Add(0);
for ( int i = 0; i <= n; i++) {
for ( int j = 0; j <= Math.Min(i, k); j++) {
if (j == 0 || j == i)
curr[j] = 1;
else
curr[j] = prev[j - 1] + prev[j];
}
prev = new List< int >(curr);
}
return curr[k];
}
public static int waysToSplitN( int k, int n, int P)
{
int new_N = n - k * P;
return binomialCoeff(new_N + k - 1, new_N);
}
public static void Main()
{
int K = 3, N = 8, P = 2;
Console.WriteLine(waysToSplitN(K, N, P));
}
}
|
Javascript
function binomialCoeff(n, k)
{
let prev = new Array(k + 1).fill(0);
let curr = new Array(k + 1).fill(0);
for (let i = 0; i <= n; i++) {
for (let j = 0; j <= Math.min(i, k); j++) {
if (j == 0 || j == i) {
curr[j] = 1;
}
else {
curr[j] = prev[j - 1] + prev[j];
}
}
prev = curr.slice();
}
return curr[k];
}
function waysToSplitN(k, n, P) {
const newN = n - k * P;
return binomialCoeff(newN + k - 1, newN);
}
const K = 3;
const N = 8;
const P = 2;
console.log(waysToSplitN(K, N, P));
|
Output:
6
Time Complexity: O(N*N)
Auxiliary Space: O(K)
Last Updated :
17 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...