Open In App

Maximum Gold Coins in Broken Blocks

Last Updated : 07 Feb, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

In the game of Broken Blocks, the player is allowed to move on m x n blocks i.e. m levels and n stone blocks on each level such that one level is vertically above the previous level (as in a staircase), with some of its stone blocks replaced by wooden blocks. The player at the start of the game is present on the ground level (which should be considered as level 0 or it can be considered as level -1). The player can start from any of the blocks present on the level 0 and start moving further to next levels. The player can only move to the stone-block just above to the present stone-block or diagonally to the left or to the right. The player can’t move on the same level. If the player steps on any of the wooden block (denoted by -1), he will fall off the board and die as the wooden block will not be able to hold player’s weight. Each of the stone-block has some gold coins present on it (wooden blocks doesn’t have any coins on them). If at any point the player can’t move to further level due to any reason, the game ends and his present total coin score will be considered. The player’s aim is to collect as many gold coins as he can without falling off the board.

Examples:

Input: matrix = {{2, 5, 6}, {-1, 3, 2}, {4, -1, 5}}
Output: 14
Explanation: Assume 0-based indexing. The matrix is:
2 5 6 (level 0)
-1 3 2 (level 1)
4 -1 5 (lever 2)
The player can collect maximum number of coins by moving through: matrix[0][2] + matrix[1][1] + matrix[2][2] = 6 + 3 + 5 = 14 coins.

Input: matrix = {{-1, 2, 3, 4}, {5, -1, -1, 2}, {4, 3, -1, -1}}
Output: 11
Explanation: The matrix is:
-1 2 3 4 (level 0)
5 -1 -1 2 (level 1)
4 3 -1 1 (level 2)
The player can collect maximum number of coins by moving through: a[0][1] + a[1][0] + a[2][0] = 2 + 5 + 4 = 11 coins.

Recommended Practice

Approach: The problem can be solved using the following approach:

The algorithm, using Dynamic Programming, calculates the maximum gold at each stone block by considering both the current and next-level blocks. Check the next level blocks and maximize the gold using the stone blocks of the next level. The highest gold on the first level represents the maximum number of gold coins we can collect.

Step-by-step algorithm:

  • Create a copy of the game board with additional columns for boundary conditions.
  • Start from the second last level and iterate upwards.
  • For each stone block on the current level:
    • If it’s not a wooden block:
      • Check the blocks on the next level.
      • If there are wooden blocks on all three possible positions, do nothing.
      • Otherwise, add the maximum gold from the next level to the current block.
  • Iterate through the blocks on the first level and find the one with the maximum gold.
    • This block represents the highest score achievable.
  • If the maximum gold is still -1 (all blocks on the first level are wooden), set the maximum gold to 0.
  • Return the maximum gold as the final result.

Below is the implementation of the above approach:

C++




#include <bits/stdc++.h>
  
using namespace std;
  
int maxGoldCollected(vector<vector<int> >& matrix)
{
    // number of levels in the game
    int levels = matrix.size();
    // number of blocks on each level
    int blocks = matrix[0].size();
    // game board with extra columns for boundary conditions
    int board[levels][blocks + 2];
  
    // Initialize the boundary blocks with -1 (wooden
    // blocks)
    for (int level = 0; level < levels; level++)
        board[level][0] = board[level][blocks + 1] = -1;
  
    // Copy the game board to our board
    for (int level = 0; level < levels; level++) {
        for (int block = 0; block < blocks; block++) {
            board[level][block + 1] = matrix[level][block];
        }
    }
  
    // Start from the second last level and go up
    for (int level = levels - 2; level >= 0; level--) {
        for (int block = 1; block <= blocks; block++) {
            // If the current block is not wooden
            if (board[level][block] != -1) {
                // If any of the blocks on the next level
                // are not wooden
                if (board[level + 1][block - 1] != -1
                    || board[level + 1][block] != -1
                    || board[level + 1][block + 1] != -1) {
                    // Add the maximum gold from the next
                    // level to the current block
                    board[level][block] += max(
                        max(board[level + 1][block - 1],
                            board[level + 1][block]),
                        board[level + 1][block + 1]);
                }
            }
        }
    }
  
    // Find the block with maximum gold on the first level
    int maxGold = board[0][1];
    for (int block = 2; block <= blocks; block++) {
        if (board[0][block] > maxGold)
            maxGold = board[0][block];
    }
  
    // If the maximum gold is -1 (all blocks are wooden),
    // return 0
    if (maxGold == -1)
        maxGold = 0;
  
    return maxGold;
}
  
int main()
{
    // Provided input
    vector<vector<int> > matrix
        = { { 2, 5, 6 }, { -1, 3, 2 }, { 4, -1, 5 } };
  
    // Call the maxGoldCollected function with the provided
    // input
    int result = maxGoldCollected(matrix);
  
    // Output the result
    cout << "The maximum gold collected is: " << result
         << endl;
  
    return 0;
}


Java




public class MaxGoldCollection {
  
    public static int maxGoldCollected(int[][] matrix) {
        // Number of levels in the game
        int levels = matrix.length;
        // Number of blocks on each level
        int blocks = matrix[0].length;
        // Game board with extra columns for boundary conditions
        int[][] board = new int[levels][blocks + 2];
  
        // Initialize the boundary blocks with -1 (wooden blocks)
        for (int level = 0; level < levels; level++) {
            board[level][0] = board[level][blocks + 1] = -1;
        }
  
        // Copy the game board to our board
        for (int level = 0; level < levels; level++) {
            System.arraycopy(matrix[level], 0, board[level], 1, blocks);
        }
  
        // Start from the second last level and go up
        for (int level = levels - 2; level >= 0; level--) {
            for (int block = 1; block <= blocks; block++) {
                // If the current block is not wooden
                if (board[level][block] != -1) {
                    // If any of the blocks on the next level are not wooden
                    if (board[level + 1][block - 1] != -1
                            || board[level + 1][block] != -1
                            || board[level + 1][block + 1] != -1) {
                        // Add the maximum gold from the next level to the current block
                        board[level][block] += Math.max(
                                Math.max(board[level + 1][block - 1],
                                        board[level + 1][block]),
                                board[level + 1][block + 1]);
                    }
                }
            }
        }
  
        // Find the block with maximum gold on the first level
        int maxGold = board[0][1];
        for (int block = 2; block <= blocks; block++) {
            maxGold = Math.max(maxGold, board[0][block]);
        }
  
        // If the maximum gold is -1 (all blocks are wooden), return 0
        if (maxGold == -1) {
            maxGold = 0;
        }
  
        return maxGold;
    }
  
    public static void main(String[] args) {
        // Provided input
        int[][] matrix = { { 2, 5, 6 }, { -1, 3, 2 }, { 4, -1, 5 } };
  
        // Call the maxGoldCollected function with the provided input
        int result = maxGoldCollected(matrix);
  
        // Output the result
        System.out.println("The maximum gold collected is: " + result);
    }
}
  
  
// This code is contributed by akshitaguprzj3


Python3




def max_gold_collected(matrix):
    # Determine the number of levels and blocks
    levels = len(matrix)
    blocks = len(matrix[0])
      
    # Create the game board with extra columns for boundary conditions
    board = [[0 for _ in range(blocks + 2)] for _ in range(levels)]
  
    # Initialize boundary blocks as wooden blocks (-1)
    for level in range(levels):
        board[level][0] = board[level][blocks + 1] = -1
  
    # Copy the provided matrix into the game board
    for level in range(levels):
        for block in range(blocks):
            board[level][block + 1] = matrix[level][block]
  
    # Traverse the game board bottom-up to calculate maximum gold
    for level in range(levels - 2, -1, -1):
        for block in range(1, blocks + 1):
            if board[level][block] != -1:
                # Check adjacent blocks on the next level
                if board[level + 1][block - 1] != -1 or board[level + 1][block] != -1 or board[level + 1][block + 1] != -1:
                    # Add maximum gold from the next level to the current block
                    board[level][block] += max(board[level + 1][block - 1], board[level + 1][block], board[level + 1][block + 1])
  
    # Find the maximum gold collected on the first level
    max_gold = board[0][1]
    for block in range(2, blocks + 1):
        if board[0][block] > max_gold:
            max_gold = board[0][block]
  
    # If the maximum gold is -1 (all blocks are wooden), set it to 0
    if max_gold == -1:
        max_gold = 0
  
    return max_gold
  
  
# Provided input
matrix = [
    [2, 5, 6],
    [-1, 3, 2],
    [4, -1, 5]
]
  
# Call the max_gold_collected function with the provided input
result = max_gold_collected(matrix)
  
# Output the result
print("The maximum gold collected is:", result)


C#




using System;
  
class Program
{
    static int MaxGoldCollected(int[][] matrix)
    {
        int levels = matrix.Length;
        int blocks = matrix[0].Length;
        int[,] board = new int[levels, blocks + 2];
  
        // Initialize the boundary blocks with -1 (wooden blocks)
        for (int level = 0; level < levels; level++)
        {
            board[level, 0] = board[level, blocks + 1] = -1;
        }
  
        // Copy the game board to our board
        for (int level = 0; level < levels; level++)
        {
            for (int block = 0; block < blocks; block++)
            {
                board[level, block + 1] = matrix[level][block];
            }
        }
  
        // Start from the second last level and go up
        for (int level = levels - 2; level >= 0; level--)
        {
            for (int block = 1; block <= blocks; block++)
            {
                // If the current block is not wooden
                if (board[level, block] != -1)
                {
                    // If any of the blocks on the next level are not wooden
                    if (board[level + 1, block - 1] != -1 ||
                        board[level + 1, block] != -1 ||
                        board[level + 1, block + 1] != -1)
                    {
                        // Add the maximum gold from the next level to the current block
                        board[level, block] += Math.Max(
                            Math.Max(board[level + 1, block - 1],
                                     board[level + 1, block]),
                            board[level + 1, block + 1]);
                    }
                }
            }
        }
  
        // Find the block with maximum gold on the first level
        int maxGold = board[0, 1];
        for (int block = 2; block <= blocks; block++)
        {
            if (board[0, block] > maxGold)
                maxGold = board[0, block];
        }
  
        // If the maximum gold is -1 (all blocks are wooden), return 0
        if (maxGold == -1)
            maxGold = 0;
  
        return maxGold;
    }
  
    static void Main()
    {
        // Provided input
        int[][] matrix = new int[][]
        {
            new int[] {2, 5, 6},
            new int[] {-1, 3, 2},
            new int[] {4, -1, 5}
        };
  
        // Call the MaxGoldCollected function with the provided input
        int result = MaxGoldCollected(matrix);
  
        // Output the result
        Console.WriteLine("The maximum gold collected is: " + result);
    }
}


Javascript




function maxGoldCollected(matrix) {
    // number of levels in the game
    const levels = matrix.length;
    // number of blocks on each level
    const blocks = matrix[0].length;
    // game board with extra columns 
    // for boundary conditions
    const board = new Array(levels);
  
    // Initialize the board and set boundary 
    // blocks to -1 (wooden blocks)
    for (let level = 0; level < levels; level++) {
        board[level] = new Array(blocks + 2).fill(0);
        board[level][0] = board[level][blocks + 1] = -1;
    }
  
    // Copy the game matrix to our board
    for (let level = 0; level < levels; level++) {
        for (let block = 0; block < blocks; block++) {
            board[level][block + 1] = matrix[level][block];
        }
    }
  
    // Start from the second last
    // level and go up
    for (let level = levels - 2; level >= 0; level--) {
        for (let block = 1; block <= blocks; block++) {
            // If the current block is not wooden
            if (board[level][block] !== -1) {
                // If any of the blocks on the 
                // next level are not wooden
                if (
                    board[level + 1][block - 1] !== -1 ||
                    board[level + 1][block] !== -1 ||
                    board[level + 1][block + 1] !== -1
                ) {
                    // Add the maximum gold from the next 
                    // level to the current block
                    board[level][block] += Math.max(
                        Math.max(board[level + 1][block - 1], board[level + 1][block]),
                        board[level + 1][block + 1]
                    );
                }
            }
        }
    }
  
    // Find the block with maximum gold
    // on the first level
    let maxGold = board[0][1];
    for (let block = 2; block <= blocks; block++) {
        if (board[0][block] > maxGold) {
            maxGold = board[0][block];
        }
    }
  
    // If the maximum gold is -1 (all 
    // blocks are wooden), return 0
    if (maxGold === -1) {
        maxGold = 0;
    }
  
    return maxGold;
}
  
// Provided input
const matrix = [
    [2, 5, 6],
    [-1, 3, 2],
    [4, -1, 5]
];
  
// Call the maxGoldCollected function 
// with the provided input
const result = maxGoldCollected(matrix);
  
// Output the result
console.log("The maximum gold collected is: " + result);


Output

The maximum gold collected is: 14








Time Complexity: O(m*n), where m is the number of levels and n is the number of stone blocks on each level.
Auxiliary Space: O(m*n)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads