Open In App

Number of ways of cutting a Matrix such that atleast one cell is filled in each part

Last Updated : 29 Jan, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given an integer K and a matrix mat[][] containing 1 and 0, where 1 denotes the cell is filled and 0 denotes an empty cell. The task is to find the number of ways to cut the matrix into K parts using K-1 cuts such that each part of the matrix contains atleast one filled cell.

For each cut, there must be a direction either horizontal or vertical. Then you choose a cut position at the cell boundary and cut the matrix into two parts. If you cut the matrix vertically, the left part of the matrix will not be used again for further process. If you cut the matrix horizontally, the upper part of the matrix will not be used again.

Examples:  

Input: mat[][] = {{1, 0, 0}, {1, 1, 1}, {0, 0, 0}}, K = 3 
Output:
Explanation: 

Input: matrix = {{1, 0, 0}, {1, 1, 0}, {0, 0, 0}}, K = 3 
Output: 1

Approach: The idea is to use Dynamic Programming to compute the number of ways of cutting a matrix with atleast one filled cell. 

  • Compute the prefix sum of the matrix such that we can compute a particular portion of the matrix contains a filled cell or not in O(1) time.
  • Define a dp table to store the number of ways to cut the pizza in K parts, where dp[k][r] denotes the number of ways to cut the matrix into K parts from top left to Rth row and Cth Column.
  • Finally, iterate over for every possible matrix and check that if the matrix can be cut into the two parts upto that index and both part is valid or not.

Below is the implementation of the above approach:

C++




// CPP implementation to find the
// number of ways to cut the matrix
// into the K parts such that each
// part have atleast one filled cell
#include <bits/stdc++.h>
using namespace std;
 
// Function  to find the number of
// ways to cut the matrix into the
// K parts such that each part have
// atleast one filled cell
int ways(vector<vector<int>> &arr, int K)
{
  int R = arr.size();
  int C = arr[0].size();
 
  int preSum[R][C];
 
  // Loop to find prefix sum of the
  // given matrix
  for (int r = R - 1; r >= 0; r--)
  {
    for (int c = C - 1; c >= 0; c--)
    {
      preSum[r] = arr[r];
 
      if (r + 1 < R) preSum[r] += preSum[r + 1];
 
      if (c + 1 < C) preSum[r] += preSum[r];
 
      if (r + 1 < R && c + 1 < C) preSum[r] -= preSum[r + 1];
    }
  }
 
  // dp(r, c, 1) = 1
  // if preSum[r] else 0
  int dp[K + 1][R][C];
 
  // Loop to iterate over the dp
  // table of the given matrix
  for (int k = 1; k <= K; k++)
  {
    for (int r = R - 1; r >= 0; r--)
    {
      for (int c = C - 1; c >= 0; c--)
      {
        if (k == 1)
        {
          dp[k][r] = (preSum[r] > 0) ? 1 : 0;
        } else {
          dp[k][r] = 0;
          for (int r1 = r + 1; r1 < R; r1++)
          {
 
            // Check if can cut horizontally
            // at r1, at least one apple in
            // matrix (r, c) -> r1, C-1
            if (preSum[r] - preSum[r1] > 0)
              dp[k][r] += dp[k - 1][r1];
          }
          for (int c1 = c + 1; c1 < C; c1++)
          {
 
            // Check if we can cut vertically
            // at c1, at least one apple in
            // matrix (r, c) -> R-1, c1
            if (preSum[r] - preSum[r][c1] > 0)
              dp[k][r] += dp[k - 1][r][c1];
          }
        }
      }
    }
  }
  return dp[K][0][0];
}
 
// Driver code
int main()
{
  vector<vector<int>> arr = {{1, 0, 0}, {1, 1, 1}, {0, 0, 0}};
  int k = 3;
 
  // Function Call
  cout << ways(arr, k) << endl;
  return 0;
}
 
// This code is contributed by sanjeev2552


Java




// Java implementation to find the 
// number of ways to cut the matrix 
// into the K parts such that each
// part have atleast one filled cell
import java.util.*;
import java.lang.*;
import java.io.*;
 
class GFG{
 
// Function  to find the number of
// ways to cut the matrix into the
// K parts such that each part have
// atleast one filled cell    
static int ways(int[][] arr, int K)
{
    int R = arr.length;
    int C = arr[0].length;
     
    int[][] preSum = new int[R][C];
     
    // Loop to find prefix sum of the 
    // given matrix
    for(int r = R - 1; r >= 0; r--)
    {
        for(int c = C - 1; c >= 0; c--)
        {
            preSum[r] = arr[r];
             
            if (r + 1 < R)
            preSum[r] += preSum[r + 1];
             
            if (c + 1 < C)
            preSum[r] += preSum[r];
             
            if (r + 1 < R && c + 1 < C)
            preSum[r] -= preSum[r + 1];
        }
    }
     
    // dp(r, c, 1) = 1 
    // if preSum[r] else 0
    int[][][] dp = new int[K + 1][R][C];
     
    // Loop to iterate over the dp 
    // table of the given matrix
    for(int k = 1; k <= K; k++)
    {
        for(int r = R - 1; r >= 0; r--)
        {
            for(int c = C - 1; c >= 0; c--)
            {
                if (k == 1)
                {
                    dp[k][r] = (preSum[r] > 0) ?
                                              1 : 0;
                }
                else
                {
                    dp[k][r] = 0;
                    for(int r1 = r + 1; r1 < R; r1++)
                    {
                         
                        // Check if can cut horizontally
                        // at r1, at least one apple in 
                        // matrix (r, c) -> r1, C-1
                        if (preSum[r] - preSum[r1] > 0)
                             dp[k][r] += dp[k - 1][r1];
                    }
                    for(int c1 = c + 1; c1 < C; c1++)
                    {
                     
                        // Check if we can cut vertically 
                        // at c1, at least one apple in 
                        // matrix (r, c) -> R-1, c1
                        if (preSum[r] - preSum[r][c1] > 0)
                            dp[k][r] += dp[k - 1][r][c1];
                    }
                }
            }
        }
    }
    return dp[K][0][0];
}
 
// Driver code
public static void main(String[] args)
{
    int[][] arr = { { 1, 0, 0 },
                    { 1, 1, 1 },
                    { 0, 0, 0 } };
    int k = 3;
       
    // Function Call
    System.out.println(ways(arr, k));
}
}
 
// This code is contributed by offbeat


Python3




# Python3 implementation to find the
# number of ways to cut the matrix
# into the K parts such that each
# part have atleast one filled cell
 
# Function  to find the
# number of ways to cut the matrix
# into the K parts such that each
# part have atleast one filled cell
def ways(arr, k):
    R = len(arr)
    C = len(arr[0])
    K = k
    preSum = [[0 for _ in range(C)]\
                 for _ in range(R)]
                  
    # Loop to find prefix sum of the
    # given matrix
    for r in range(R-1, -1, -1):
        for c in range(C-1, -1, -1):
            preSum[r] = arr[r]
             
            if r + 1 < R:
                preSum[r] += preSum[r + 1]
            if c + 1 < C:
                preSum[r] += preSum[r]
                 
            if r + 1 < R and c + 1 < C:
                preSum[r] -= preSum[r + 1]
     
    # dp(r, c, 1) = 1
    # if preSum[r] else 0
    dp = [[[0 for _ in range(C)]\
              for _ in range(R)]\
              for _ in range(K + 1)]
               
    # Loop to iterate over the dp
    # table of the given matrix
    for k in range(1, K + 1):
        for r in range(R-1, -1, -1):
            for c in range(C-1, -1, -1):
                if k == 1:
                    dp[k][r] = 1 \
                        if preSum[r] > 0\
                        else 0
                else:
                    dp[k][r] = 0
                    for r1 in range(r + 1, R):
                         
                        # Check if can cut horizontally
                        # at r1, at least one apple in
                        # matrix (r, c) -> r1, C-1
                        if preSum[r] - preSum[r1] > 0:
                            dp[k][r] += dp[k-1][r1]
                    for c1 in range(c + 1, C):
                         
                        # Check if we can cut vertically
                        # at c1, at least one apple in
                        # matrix (r, c) -> R-1, c1
                        if preSum[r] - preSum[r][c1] > 0:
                            dp[k][r] += dp[k-1][r][c1]
    return dp[K][0][0]
     
# Driver Code
if __name__ == "__main__":
    arr = [[1, 0, 0], [1, 1, 1], [0, 0, 0]]
    k = 3
     
    # Function Call
    print(ways(arr, k))


C#




// C# implementation to find the
// number of ways to cut the matrix
// into the K parts such that each
// part have atleast one filled cell
using System;
class GFG {
 
    // Function  to find the number of
    // ways to cut the matrix into the
    // K parts such that each part have
    // atleast one filled cell
    static int ways(int[, ] arr, int K)
    {
        int R = arr.GetLength(0);
        int C = arr.GetLength(1);
 
        int[, ] preSum = new int[R, C];
 
        // Loop to find prefix sum of the
        // given matrix
        for (int r = R - 1; r >= 0; r--) {
            for (int c = C - 1; c >= 0; c--) {
                preSum[r, c] = arr[r, c];
 
                if (r + 1 < R)
                    preSum[r, c] += preSum[r + 1, c];
 
                if (c + 1 < C)
                    preSum[r, c] += preSum[r, c + 1];
 
                if (r + 1 < R && c + 1 < C)
                    preSum[r, c] -= preSum[r + 1, c + 1];
            }
        }
 
        // dp(r, c, 1) = 1
        // if preSum[r] else 0
        int[, , ] dp = new int[K + 1, R, C];
 
        // Loop to iterate over the dp
        // table of the given matrix
        for (int k = 1; k <= K; k++) {
            for (int r = R - 1; r >= 0; r--) {
                for (int c = C - 1; c >= 0; c--) {
                    if (k == 1) {
                        dp[k, r, c]
                            = (preSum[r, c] > 0) ? 1 : 0;
                    }
                    else {
                        dp[k, r, c] = 0;
                        for (int r1 = r + 1; r1 < R; r1++) {
 
                            // Check if can cut horizontally
                            // at r1, at least one apple in
                            // matrix (r, c) -> r1, C-1
                            if (preSum[r, c] - preSum[r1, c]
                                > 0)
                                dp[k, r, c]
                                    += dp[k - 1, r1, c];
                        }
                        for (int c1 = c + 1; c1 < C; c1++) {
 
                            // Check if we can cut
                            // vertically at c1, at least
                            // one apple in matrix (r, c) ->
                            // R-1, c1
                            if (preSum[r, c] - preSum[r, c1]
                                > 0)
                                dp[k, r, c]
                                    += dp[k - 1, r, c1];
                        }
                    }
                }
            }
        }
        return dp[K, 0, 0];
    }
 
    // Driver code
    public static void Main(string[] args)
    {
        int[, ] arr
            = { { 1, 0, 0 }, { 1, 1, 1 }, { 0, 0, 0 } };
        int k = 3;
 
        // Function Call
        Console.WriteLine(ways(arr, k));
    }
}
 
// This code is contributed by ukasp.


Javascript




<script>
// Javascript implementation to find the
// number of ways to cut the matrix
// into the K parts such that each
// part have atleast one filled cell
 
// Function  to find the number of
// ways to cut the matrix into the
// K parts such that each part have
// atleast one filled cell   
function ways(arr, K)
{
    let R = arr.length;
    let C = arr[0].length;
      
    let preSum = new Array(R);
    for(let i = 0; i < R; i++)
    {
        preSum[i] = new Array(C);
        for(let j = 0; j < C; j++)
        {
            preSum[i][j] = 0;
        }
    }
      
    // Loop to find prefix sum of the
    // given matrix
    for(let r = R - 1; r >= 0; r--)
    {
        for(let c = C - 1; c >= 0; c--)
        {
            preSum[r] = arr[r];
              
            if (r + 1 < R)
            preSum[r] += preSum[r + 1];
              
            if (c + 1 < C)
            preSum[r] += preSum[r];
              
            if (r + 1 < R && c + 1 < C)
            preSum[r] -= preSum[r + 1];
        }
    }
      
    // dp(r, c, 1) = 1
    // if preSum[r] else 0
    let dp = new Array(K + 1);
    for(let i = 0; i < dp.length; i++)
    {
        dp[i] = new Array(R);
        for(let j = 0; j < R; j++)
        {
            dp[i][j] = new Array(C);
            for(let k = 0; k < C; k++)
            {
                dp[i][j][k] = 0;
            }
        }
    }
      
    // Loop to iterate over the dp
    // table of the given matrix
    for(let k = 1; k <= K; k++)
    {
        for(let r = R - 1; r >= 0; r--)
        {
            for(let c = C - 1; c >= 0; c--)
            {
                if (k == 1)
                {
                    dp[k][r] = (preSum[r] > 0) ?
                                              1 : 0;
                }
                else
                {
                    dp[k][r] = 0;
                    for(let r1 = r + 1; r1 < R; r1++)
                    {
                          
                        // Check if can cut horizontally
                        // at r1, at least one apple in
                        // matrix (r, c) -> r1, C-1
                        if (preSum[r] - preSum[r1] > 0)
                             dp[k][r] += dp[k - 1][r1];
                    }
                    for(let c1 = c + 1; c1 < C; c1++)
                    {
                      
                        // Check if we can cut vertically
                        // at c1, at least one apple in
                        // matrix (r, c) -> R-1, c1
                        if (preSum[r] - preSum[r][c1] > 0)
                            dp[k][r] += dp[k - 1][r][c1];
                    }
                }
            }
        }
    }
    return dp[K][0][0];
}
 
// Driver code
let arr = [[1, 0, 0 ],
                    [ 1, 1, 1 ],
                    [ 0, 0, 0 ]];
    let k = 3;
        
    // Function Call
    document.write(ways(arr, k));
 
// This code is contributed by avanitrachhadiya2155.
</script>


Output

3

Time Complexity: O(K*N*M)
Auxilary Space: O(K*N*M)



Similar Reads

Minimum moves taken to move coin of each cell to any one cell of Matrix
Given an odd number N which represents a grid of size N x N which is initially filled by coins, the task is to find the minimum number of moves required for all the coins to move to any cell of the grid such that in each step, some arbitrary coin in the middle of the grid can move to any of the surrounding eight cells. Examples: Input: N = 3 Output
6 min read
Minimum number of flips required such that the last cell of matrix can be reached from any other cell
Given a matrix arr[][] of dimensions N * M where each cell consists of characters 'R' or 'D' except the cell arr[N][M] which contains 'F'. 'R' and 'D' denotes that the player can move in the right and down direction respectively from the current cell. The task is to find the minimum number of characters required to be flipped from 'R' to 'D' or 'D'
6 min read
Find path traveling which bishop traverse each black cell atleast once
Given two integers X and Y such that X+Y is even, Which denotes the initial position of the bishop on a chessboard of 8 x 8 dimension. Then the task is to output a continuous path with not more than 32 coordinates(total black cells on board) such that traveling on that path bishop covers all the cells (i, j) having even sum (i + j = even). These ce
8 min read
Construct a Matrix such that each cell consists of sum of adjacent elements of respective cells in given Matrix
Given a matrix arr[][] of dimensions N * M, the task is to generate a matrix such that any cell (r, c) stores the sum of adjacent elements present horizontally, vertically, and diagonally in the given matrix. Examples: Input: arr[][] = {{1, 3}, {2, 4}}Output: {{9, 7}, {8, 6}}Explanation: Matrix is constructed by the following operations: For cell (
9 min read
Number of ways an array can be filled with 0s and 1s such that no consecutive elements are 1
Given a number N, find the number of ways to construct an array of size N such that it contains only 1s and 0s but no two consecutive indexes have value 1 in them. Examples: Input : 2 Output : 3 Explanation: For n=2, the possible arrays are: {0, 1} {1, 0} {0, 0} Input : 3 Output : 5 Explanation: For n=3, the possible arrays are: {0, 0, 0} {1, 0, 0}
6 min read
Number of Positions to partition the string such that atleast m characters with same frequency are present in each substring
Given a string str of lowercase English alphabets and an integer m. The task is to count how many positions are there in the string such that if you partition the string into two non-empty sub-strings, there are at least m characters with the same frequency in both sub-strings. The characters need to be present in the string str.Examples: Input: st
16 min read
Minimize the number of turns needed to reach from top left cell to bottom right cell of the matrix.
Given a binary 2D matrix maze[][] of size N X N such that a cell (r, c) is blocked if maze[r][c][/c] = 0 and unblocked if maze[r][c][/c] = 1, the task is to start from cell (0, 0) to reach (N - 1, N - 1) by minimizing the number of turns. We can take any of the four directions (Up, Left, Right, Down) as the starting direction. Then, from each cell,
12 min read
Maximum triplets containing atleast one x and one y
Given counts of x, y, and z, the task is to find the maximum number of triplets that can be made from the count of x, y, and z such that one triplet contains at least one x and at least one y. It is not necessary to use all x, y, and z. Examples: Input: countX = 2, countY = 1, countZ = 3Output: 1Explanation: The first triplet contains one x, one y,
20 min read
Leftmost Column with atleast one 1 in a row-wise sorted binary matrix
Given a binary matrix mat[][] containing 0's and 1's. Each row of the matrix is sorted in the non-decreasing order, the task is to find the left-most column of the matrix with at least one 1 in it.Note: If no such column exists return -1.Examples: Input: mat[2][2] = { {0, 0}, {1, 1} } Output: 1 Explanation: The 1st column of the matrix contains atl
8 min read
Leftmost Column with atleast one 1 in a row-wise sorted binary matrix | Set 2
Given a binary matrix mat[][] containing 0’s and 1’s. Each row of the matrix is sorted in the non-decreasing order, the task is to find the left-most column of the matrix with at least one 1 in it.Note: If no such column exists return -1. Examples: Input: mat[][] = {{0, 0, 0, 1} {0, 1, 1, 1} {0, 0, 1, 1}} Output: 2 Explanation: The 2nd column of th
5 min read