Stars and Bars Algorithms for Competitive Programming
Last Updated :
29 Feb, 2024
The Stars and Bars (also known as Balls and Urns) technique is a popular method used in Combinatorics, the study of counting and arrangement. It's a graphical way to solve certain types of problems and is particularly useful when dealing with problems related to the distribution of identical objects into distinct groups. This article will introduce the concept of Stars and Bars algorithm in depth, including some examples and a detailed explanation of how it is implemented. In addition, we are going to show you some of the use cases it has with real-life applications.

Stars and Bars Algorithms:
The Stars and Bars approach is based on a simple yet powerful concept. Imagine you have n identical objects (which we represent as stars) that you want to distribute into k distinct groups (which we represent as bars). The Stars and Bars theorem states that there are C(n+k-1, k-1) ways to do this, where C denotes the binomial coefficient.
This approach allows us to visualize the problem in a way that makes it easier to understand and solve. By representing the objects and groups as stars and bars, we can see the different ways the objects can be distributed among the groups.
This method becomes particularly useful in scenarios where the distribution of objects into groups follows specific constraints. Let's explore two variations of the Stars and Bars approach to illustrate its versatility:
1. Distribution among groups where groups can have 0 objects:
Imagine you have N identical objects (which we represent as stars) that you want to distribute into K distinct groups, such that each group can have 0 to N number of elements. The Stars and Bars theorem states that there are C(N+K-1, K-1) ways to do this, where C denotes the binomial coefficient.
This approach allows us to visualize the problem in a way that makes it easier to understand and solve. By representing the objects as stars and bars, we can see the different ways the objects can be distributed among the groups.
Example:
Let's consider an example where we have 4 identical objects (stars) and we want to distribute them into 2 distinct groups. So, all the possible distributions are:
-768.png)
From the above image, we can see that the number of ways to distribute 4 objects among 2 groups is same as having 5 blanks and finding the number of ways to fill those blanks with 4 stars (or 1 partition). In order to distribute N objects to K groups we will need K-1 partitions, so the total number of blanks will be (N+K-1) and number of objects to be distributed are N. Similarly, we can extend our observation to get the formula for N objects to be distributed among K groups as C(N + K - 1, N) or C(N + K - 1, K - 1).
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
// Function to calculate C(N, R)
int C(int N, int R)
{
R = min(R, N - R);
int ans = 1;
for (int i = 0; i < R; i++) {
ans = ans * (N - i);
ans = ans / (i + 1);
}
return ans;
}
// Function to get ways where groups can have 0 objects
int getWaysWithZero(int N, int K)
{
return C(N + K - 1, K - 1);
}
int main()
{
// Number of objects and groups
int N = 4, K = 2;
cout << "Ways to divide " << N << " objects among " << K
<< " groups such that a group can have 0 objects "
"are "
<< getWaysWithZero(N, K) << endl;
return 0;
}
Java
import java.util.*;
class GFG {
// Function to calculate C(N, R)
static int C(int N, int R) {
// Ensure R is not greater than N - R
R = Math.min(R, N - R);
int ans = 1;
for (int i = 0; i < R; i++) {
ans = ans * (N - i);
ans = ans / (i + 1);
}
return ans;
}
// Function to get ways where groups can have 0 objects
static int getWaysWithZero(int N, int K) {
// Calculate C(N + K - 1, K - 1)
return C(N + K - 1, K - 1);
}
public static void main(String[] args) {
// Number of objects and groups
int N = 4, K = 2;
// Display the result
System.out.println("Ways to divide " + N + " objects among " + K +
" groups such that a group can have 0 objects are " +
getWaysWithZero(N, K));
}
}
Python3
# Function to calculate C(N, R)
def C(N, R):
R = min(R, N - R)
ans = 1
for i in range(R):
ans = ans * (N - i)
ans = ans // (i + 1)
return ans
# Function to get ways where groups can have 0 objects
def getWaysWithZero(N, K):
return C(N + K - 1, K - 1)
# Number of objects and groups
N, K = 4, 2
print("Ways to divide", N, "objects among", K,
"groups such that a group can have 0 objects are",
getWaysWithZero(N, K))
C#
using System;
class Program
{
// Function to calculate C(N, R)
static int C(int N, int R)
{
// Ensure R is not greater than N - R
R = Math.Min(R, N - R);
int ans = 1;
for (int i = 0; i < R; i++)
{
ans = ans * (N - i);
ans = ans / (i + 1);
}
return ans;
}
// Function to get ways where groups can have 0 objects
static int GetWaysWithZero(int N, int K)
{
// Calculate C(N + K - 1, K - 1)
return C(N + K - 1, K - 1);
}
static void Main()
{
// Number of objects and groups
int N = 4, K = 2;
// Display the result
Console.WriteLine($"Ways to divide {N} objects among {K} groups such that a group can have 0 objects are {GetWaysWithZero(N, K)}");
}
}
JavaScript
function C(N, R) {
// Ensure R is not greater than N - R
R = Math.min(R, N - R);
let ans = 1;
for (let i = 0; i < R; i++) {
ans = ans * (N - i);
ans = ans / (i + 1);
}
return ans;
}
function getWaysWithZero(N, K) {
// Calculate C(N + K - 1, K - 1)
return C(N + K - 1, K - 1);
}
// Number of objects and groups
let N = 4;
let K = 2;
// Display the result
console.log(`Ways to divide ${N} objects among ${K} groups such that a group can have 0 objects are ${getWaysWithZero(N, K)}`);
OutputWays to divide 4 objects among 2 groups such that a group can have 0 objects are 5
Time Complexity: O(K), where K is the number of groups among which objects are distributed.
Auxiliary Space: O(1)
2. Distribution among groups where groups cannot have 0 objects:
Imagine you have N identical objects (which we represent as stars) that you want to distribute into K distinct groups, such that each group should have at least 1 object. The Stars and Bars theorem states that there are C(N-1, K-1) ways to do this, where C denotes the binomial coefficient.
Example:
Let's consider an example where we have 4 identical objects (stars) and we want to distribute them into 2 distinct groups such that each group should have at least one object. So, all the possible distributions are:
-768.png)
From the above image, we can see that the number of ways to distribute 4 objects among 2 groups such that each group should have at least one object then it is same as fixing the position of stars and then having the choice to fill one of the remaining blank with a partition. In order to distribute N objects to K groups we will fix the positions of all the N stars and out of the remaining (N-1) blanks between stars we can place (K-1) partitions in them, so the total number of blanks will be (N-1) and number of partitions to be placed would be (K-1). So, we can extend our observation to get the formula for N objects to be distributed among K groups such that each group gets at least one object as C(N - 1, K - 1).
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
// Function to calculate C(N, R)
int C(int N, int R)
{
R = min(R, N - R);
int ans = 1;
for (int i = 0; i < R; i++) {
ans = ans * (N - i);
ans = ans / (i + 1);
}
return ans;
}
// Function to get ways where groups cannot have 0 objects
int getWaysWithoutZero(int N, int K)
{
return C(N - 1, K - 1);
}
int main()
{
// Number of objects and groups
int N = 4, K = 2;
cout << "Ways to divide " << N << " objects among " << K
<< " groups such that a group cannot have 0 "
"objects are "
<< getWaysWithoutZero(N, K) << endl;
return 0;
}
Java
import java.util.Scanner;
public class Solution {
// Function to calculate C(N, R)
static int C(int N, int R) {
R = Math.min(R, N - R);
int ans = 1;
for (int i = 0; i < R; i++) {
ans = ans * (N - i);
ans = ans / (i + 1);
}
return ans;
}
// Function to get ways where groups cannot have 0 objects
static int getWaysWithoutZero(int N, int K) {
return C(N - 1, K - 1);
}
public static void main(String[] args) {
// Number of objects and groups
int N = 4, K = 2;
System.out.println("Ways to divide " + N + " objects among " + K +
" groups such that a group cannot have 0 objects are " +
getWaysWithoutZero(N, K));
}
}
// This code is contributed by shivamgupta310570
Python3
import math
# Function to calculate C(N, R)
def C(N, R):
R = min(R, N - R)
ans = 1
for i in range(R):
ans = ans * (N - i)
ans = ans // (i + 1)
return ans
# Function to get ways where groups cannot have 0 objects
def getWaysWithoutZero(N, K):
return C(N - 1, K - 1)
# Number of objects and groups
N = 4
K = 2
print(f"Ways to divide {N} objects among {K} groups such that a group cannot have 0 objects are {getWaysWithoutZero(N, K)}")
C#
using System;
class Program
{
// Function to calculate C(N, R)
static int C(int N, int R)
{
R = Math.Min(R, N - R);
int ans = 1;
for (int i = 0; i < R; i++)
{
ans = ans * (N - i);
ans = ans / (i + 1);
}
return ans;
}
// Function to get ways where groups cannot have 0 objects
static int GetWaysWithoutZero(int N, int K)
{
return C(N - 1, K - 1);
}
static void Main(string[] args)
{
// Number of objects and groups
int N = 4, K = 2;
Console.WriteLine($"Ways to divide {N} objects among {K} groups such that a group cannot have 0 objects are {GetWaysWithoutZero(N, K)}");
}
}
JavaScript
// Function to calculate C(N, R)
function C(N, R) {
R = Math.min(R, N - R);
let ans = 1;
for (let i = 0; i < R; i++) {
ans = ans * (N - i);
ans = Math.floor(ans / (i + 1));
}
return ans;
}
// Function to get ways where groups cannot have 0 objects
function getWaysWithoutZero(N, K) {
return C(N - 1, K - 1);
}
// Number of objects and groups
const N = 4, K = 2;
console.log("Ways to divide " + N + " objects among " + K +
" groups such that a group cannot have 0 objects are " +
getWaysWithoutZero(N, K));
OutputWays to divide 4 objects among 2 groups such that a group cannot have 0 objects are 3
Time Complexity: O(K), where K is the number of groups among which objects are distributed.
Auxiliary Space: O(1)
Stars and Bars Use Cases:
1. Distributing Objects into Groups:
We can use Stars and Bars Approach to find the number of ways to distribute N objects among K groups for both the cases, when a group can have zero objects as well as when a group should have at least one object. The approach as well as the implementation has been discussed above.
2. Finding the number of Solutions of Equations:
The Stars and Bars approach can also be used to find the number of solutions to the equations like x1 + x2 + x3 .... = S, such that xi >= 1. For example: x1 + x2 + x3 = 10, where x1, x2, and x3 are non-negative integers.
Here, the stars would represent units of 1, and the bars would separate the different variables. According to the Stars and Bars theorem, there are C(10+3-1, 3-1) = C(12, 2) = 66 solutions to this equation.
Similarly, if x1, x2 and x3 are positive numbers then according to the Stars and Bars theorem, there are C(10 - 1, 3 - 1) = C(9, 2) = 36 solutions to this equation.
3. Finding the number of Solutions of Equations with a lower bound restrictions on Solutions:
The Stars and Bars approach can also be used to find the number of solutions to the equations like x1 + x2 + x3 .... = S, when we are given lower bounds that x1 >= y1, x2 >= y2 and x3 >= y3... and so on.
So, if we substitute x1 with x1', x2 with x2' and xi with xi' such that xi' = (xi - yi). So, the new equation would be:
(x1' + y1) + (x2' + y2) + (x3' + y3) .... = S, which can be further simplified to
x1' + x2' + x3' .... = S - y1 - y2 - y2..., such that x1', x2', x3' .... are >= 0.
Now, we can again use Stars and Bars approach as we used in the above use case to get the number of solutions.
Real Life Applications of Stars and Bars:
The Stars and Bars approach is a powerful tool in combinatorics with a wide range of applications. Here are a few examples:
- Combinatorial Design: In combinatorial design, the Stars and Bars approach can be used to construct designs with certain properties. For example, it can be used to determine the number of ways to design an experiment or survey.
- Computer Science: In computer science, the Stars and Bars approach can be used in algorithm design and analysis. For example, it can be used to count the number of ways to allocate resources or to distribute tasks among processors.
- Coding Theory: In coding theory, the Stars and Bars approach can be used to count the number of codewords of a certain weight in a block code.
Conclusion:
Mastering the Stars and Bars algorithm is essential for competitive programming, offering a powerful technique for solving combinatorial problems efficiently. It provides a simple and intuitive method for solving complex counting problems. By visualizing the problem in terms of stars and bars, we can often find solutions more easily and quickly. Remember, like any tool, it's most effective when used appropriately and in the right context.
Related Article:
Similar Reads
Dijkstra's Algorithm for Competitive Programming
Dijkstra's algorithm, devised by computer scientist Edsger Dijkstra, is a fundamental graph search algorithm used to find the shortest path between nodes in a weighted graph. In this article, we will learn about how Dijkstra's algorithm can be used for solving problems in Competitive Programming. Ta
15+ min read
7 Best Books for Competitive Programming
Do you have a dream to win a Gold Medal in the Olympics of Programming (ACM ICPC)? Do you want to ace your career with Google Kickstart or want to win a prize amount of $20,000 to become a world champion in Facebook Hackercup or Google Code jam? Then you have to be an out-of-the-box problem solver.
8 min read
Learning the art of Competitive Programming
Learning the art of Competitive Programming How to begin with Competitive Programming?Top 10 Algorithms and Data Structures for Competitive ProgrammingHow to prepare for ACM â ICPC?How to prepare for Google Asia Pacific University (APAC) Test ?Remaining Ahead in Competitive Programming:Master in com
2 min read
A Better Way To Approach Competitive Programming
This article helps to all those who want to begin with Competitive Programming. The only prerequisite one need is the knowledge of a programming language. Now, Let us find a better approach to Competitive Programming. Please note: One should read the proper Input and Output format because most of th
4 min read
How to Get Started with Competitive Programming?
If you're a Computer Science student or a coding enthusiast, chances are more you've heard individuals discussing their Competitive Programming skills and rankings & achievements in various coding challenges or contests. And truly, Competitive Programming skills are one of those few skills that
8 min read
How to read Competitive Programming Questions?
Competitive Programming is considered as a sport in the field of computer science. The culture of this sport is growing day by day and a lot of people are also considering this as a career choice. So, to help the participants with improving their efficiency in this sport, in this post, we have tried
5 min read
Closest Pair of Points using Divide and Conquer algorithm
We are given an array of n points in the plane, and the problem is to find out the closest pair of points in the array. This problem arises in a number of applications. For example, in air-traffic control, you may want to monitor planes that come too close together, since this may indicate a possibl
15+ min read
My Journey of Competitive Programming
Hello geeks, Today I want to share with you my competitive programming journey. Competitive programming means solving problems in different platforms. There are many benefits to do this. Even many companies directly select candidates through their coding profile. And you can also add this profile in
3 min read
Implementation of Exhaustive Search Algorithm for Set Packing
Exhaustive Search Algorithm: Exhaustive Search is a brute-force algorithm that systematically enumerates all possible solutions to a problem and checks each one to see if it is a valid solution. This algorithm is typically used for problems that have a small and well-defined search space, where it i
11 min read
Greedy Algorithms (General Structure and Applications)
A greedy algorithm solves problems by making the best choice at each step. Instead of looking at all possible solutions, it focuses on the option that seems best right now. Problem structure:Most of the problems where greedy algorithms work follow these two properties: 1). Greedy Choice Property:- T
5 min read