Max Sum in a 2 * n Grid with No Two Adjacent

Last Updated : 13 Jun, 2026

Given a grid mat of dimension 2 * n, the task is to find out the maximum sum such that no two chosen numbers are adjacent, vertically, diagonally or horizontally.

Examples: 

Input: mat = [[1, 4, 5], [2, 0, 0]]
Output: 7
Explanation: Choose 2 from the first column and 5 from the third column. Their sum is 7.

Input: mat = [[1, 2], [3, 4]]
Output: 4
Explanation: Choose 4 from the second column. The maximum obtainable sum is 4.

Try It Yourself
redirect icon

[Naive Approach] Using Recursion - O(2 ^ n) Time O(n) Space

The idea is to process the matrix column by column. For each column, either pick the maximum value from the current column and move to column i + 2, or skip the current column and move to column i + 1. Recursively explore both choices and return the maximum sum obtained.

C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int solve(int idx, vector<vector<int>> &mat, int n)
{
    if (idx >= n)
        return 0;

    // Take current column
    int take = max(mat[0][idx], mat[1][idx]) + solve(idx + 2, mat, n);

    // Skip current column
    int skip = solve(idx + 1, mat, n);

    return max(take, skip);
}

int maxSum(vector<vector<int>> &mat)
{
    int n = mat[0].size();

    return solve(0, mat, n);
}

// Driver Code
int main()
{
    vector<vector<int>> mat = {{1, 4, 5}, {2, 0, 0}};

    cout << maxSum(mat);

    return 0;
}
Java
import java.util.ArrayList;
import java.util.List;

public class GfG {
    static int solve(int idx, List<List<Integer> > mat,
                     int n)
    {
        if (idx >= n)
            return 0;

        // Take current column
        int take = Math.max(mat.get(0).get(idx),
                            mat.get(1).get(idx))
                   + solve(idx + 2, mat, n);

        // Skip current column
        int skip = solve(idx + 1, mat, n);

        return Math.max(take, skip);
    }

    static int maxSum(List<List<Integer> > mat)
    {
        int n = mat.get(0).size();

        return solve(0, mat, n);
    }

    // Driver Code
    public static void main(String[] args)
    {
        List<List<Integer> > mat = new ArrayList<>();
        mat.add(new ArrayList<>(List.of(1, 4, 5)));
        mat.add(new ArrayList<>(List.of(2, 0, 0)));

        System.out.println(maxSum(mat));
    }
}
Python
def solve(idx, mat, n):
    if idx >= n:
        return 0

    # Take current column
    take = max(mat[0][idx], mat[1][idx]) + solve(idx + 2, mat, n)

    # Skip current column
    skip = solve(idx + 1, mat, n)

    return max(take, skip)


def maxSum(mat):
    n = len(mat[0])

    return solve(0, mat, n)


# Driver Code
if __name__ == "__main__":
    mat = [[1, 4, 5], [2, 0, 0]]

    print(maxSum(mat))
C#
using System;
using System.Collections.Generic;

public class GfG {
    static int Solve(int idx, List<List<int> > mat, int n)
    {
        if (idx >= n)
            return 0;

        // Take current column
        int take = Math.Max(mat[0][idx], mat[1][idx])
                   + Solve(idx + 2, mat, n);

        // Skip current column
        int skip = Solve(idx + 1, mat, n);

        return Math.Max(take, skip);
    }

    static int MaxSum(List<List<int> > mat)
    {
        int n = mat[0].Count;

        return Solve(0, mat, n);
    }

    // Driver Code
    public static void Main(string[] args)
    {
        List<List<int> > mat = new List<List<int> >{
            new List<int>{ 1, 4, 5 },
            new List<int>{ 2, 0, 0 }
        };

        Console.WriteLine(MaxSum(mat));
    }
}
JavaScript
function solve(idx, mat, n)
{
    if (idx >= n)
        return 0;

    // Take current column
    let take = Math.max(mat[0][idx], mat[1][idx])
               + solve(idx + 2, mat, n);

    // Skip current column
    let skip = solve(idx + 1, mat, n);

    return Math.max(take, skip);
}

function maxSum(mat)
{
    let n = mat[0].length;

    return solve(0, mat, n);
}

// Driver Code
let mat = [ [ 1, 4, 5 ], [ 2, 0, 0 ] ];

console.log(maxSum(mat));

Output
7

Time Complexity: O(2 ^ n)
Auxiliary Space: O(n)

[Expected Approach] Using Dynamic Programming - O(n) Time O(1) Space

The idea is to process the matrix column by column while maintaining three states representing whether the top cell, bottom cell, or no cell was selected in the previous column. Update these states for each column and keep only the previous column values to achieve constant extra space.

Let us understand with example:
Input: mat = [[1, 4, 5], [2, 0, 0]]

  • Initialize the states using the first column as: prev_top = 1, prev_bot = 2 and prev_none = 0.
  • For column 1, the states become: curr_top = 4, curr_bot = 0 and curr_none = 2.
  • For column 2, the states become: curr_top = 7, curr_bot = 2 and curr_none = 4.

The final answer is max(7, 2, 4) = 7.

C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int maxSum(vector<vector<int>> &mat)
{
    if (mat.empty() || mat[0].empty())
        return 0;

    int n = mat[0].size();

    if (n == 1)
    {
        return max(mat[0][0], mat[1][0]);
    }

    // prev2 = dp[i-2], prev1 = dp[i-1]
    // At each column i, best we can get considering cols 0..i
    // dp[i] = max sum ending considerations at col i

    // For each column, we have 3 choices:
    // 1. Take neither cell in this column
    // 2. Take top cell mat[0][i]
    // 3. Take bottom cell mat[1][i]
    // (can't take both in same column - they are vertically adjacent)

    // dp_top[i]    = max sum where last pick was mat[0][i]
    // dp_bot[i]    = max sum where last pick was mat[1][i]
    // dp_none[i]   = max sum where nothing picked at col i

    int prev_top = mat[0][0];
    int prev_bot = mat[1][0];
    int prev_none = 0;

    for (int i = 1; i < n; i++)
    {
        int curr_top, curr_bot, curr_none;

        // Take top cell at col i:
        // previous col must NOT have taken top or bottom
        // (horizontal adjacency with top, diagonal adjacency with bottom)
        // So previous must be none
        curr_top = prev_none + mat[0][i];

        // Take bottom cell at col i:
        // previous col must be none (same reason)
        curr_bot = prev_none + mat[1][i];

        // Take nothing at col i:
        // previous can be top, bottom, or none
        curr_none = max({prev_top, prev_bot, prev_none});

        prev_top = curr_top;
        prev_bot = curr_bot;
        prev_none = curr_none;
    }

    return max({prev_top, prev_bot, prev_none});
}

// Driver Code
int main()
{
    vector<vector<int>> mat = {{1, 4, 5}, {2, 0, 0}};

    cout << maxSum(mat);

    return 0;
}
Java
import java.util.*;

public class GfG {

    static int maxSum(List<List<Integer> > mat)
    {

        if (mat.size() == 0 || mat.get(0).size() == 0)
            return 0;

        int n = mat.get(0).size();

        if (n == 1)
            return Math.max(mat.get(0).get(0),
                            mat.get(1).get(0));

        int prevTop = mat.get(0).get(0);
        int prevBot = mat.get(1).get(0);
        int prevNone = 0;

        for (int i = 1; i < n; i++) {

            int currTop, currBot, currNone;

            currTop = prevNone + mat.get(0).get(i);
            currBot = prevNone + mat.get(1).get(i);

            currNone = Math.max(
                prevTop, Math.max(prevBot, prevNone));

            prevTop = currTop;
            prevBot = currBot;
            prevNone = currNone;
        }

        return Math.max(prevTop,
                        Math.max(prevBot, prevNone));
    }

    // Driver Code
    public static void main(String[] args)
    {

        List<List<Integer> > mat = new ArrayList<>();

        mat.add(Arrays.asList(1, 4, 5));
        mat.add(Arrays.asList(2, 0, 0));

        System.out.println(maxSum(mat));
    }
}
Python
def maxSum(mat):
    if not mat or not mat[0]:
        return 0

    n = len(mat[0])

    if n == 1:
        return max(mat[0][0], mat[1][0])

    prev_top = mat[0][0]
    prev_bot = mat[1][0]
    prev_none = 0

    for i in range(1, n):
        curr_top = prev_none + mat[0][i]
        curr_bot = prev_none + mat[1][i]
        curr_none = max(prev_top, prev_bot, prev_none)

        prev_top = curr_top
        prev_bot = curr_bot
        prev_none = curr_none

    return max(prev_top, prev_bot, prev_none)


# Driver Code
if __name__ == "__main__":
    mat = [[1, 4, 5], [2, 0, 0]]
    print(maxSum(mat))
C#
using System;
using System.Collections.Generic;

public class GfG {
    public int maxSum(List<List<int> > mat)
    {
        if (mat.Count == 0 || mat[0].Count == 0)
            return 0;

        int n = mat[0].Count;

        if (n == 1)
            return Math.Max(mat[0][0], mat[1][0]);

        int prev_top = mat[0][0];
        int prev_bot = mat[1][0];
        int prev_none = 0;

        for (int i = 1; i < n; i++) {
            int curr_top, curr_bot, curr_none;

            curr_top = prev_none + mat[0][i];
            curr_bot = prev_none + mat[1][i];
            curr_none = Math.Max(
                Math.Max(prev_top, prev_bot), prev_none);

            prev_top = curr_top;
            prev_bot = curr_bot;
            prev_none = curr_none;
        }

        return Math.Max(Math.Max(prev_top, prev_bot),
                        prev_none);
    }

    // Driver Code
    public static void Main()
    {
        List<List<int> > mat = new List<List<int> >{
            new List<int>{ 1, 4, 5 },
            new List<int>{ 2, 0, 0 }
        };

        GfG ob = new GfG();
        Console.WriteLine(ob.maxSum(mat));
    }
}
JavaScript
function maxSum(mat) {
    if (mat.length === 0 || mat[0].length === 0)
        return 0;

    let n = mat[0].length;

    if (n === 1)
        return Math.max(mat[0][0], mat[1][0]);

    let prev_top = mat[0][0];
    let prev_bot = mat[1][0];
    let prev_none = 0;

    for (let i = 1; i < n; i++) {
        let curr_top = prev_none + mat[0][i];
        let curr_bot = prev_none + mat[1][i];
        let curr_none = Math.max(prev_top, Math.max(prev_bot, prev_none));

        prev_top = curr_top;
        prev_bot = curr_bot;
        prev_none = curr_none;
    }

    return Math.max(prev_top, Math.max(prev_bot, prev_none));
}

// Driver Code
let mat = [[1, 4, 5], [2, 0, 0]];
console.log(maxSum(mat));

Output
7

Time Complexity: O(n)
Auxiliary Space: O(1)

Comment