Related Articles

# Maximum sum of points over K buildings of N floors with M jumps

• Last Updated : 01 Oct, 2021

Given K buildings with N floors and a person standing on the ground who can make at most M jumps. The person has to climb to the top and collect maximum points. Find the maximum number of points that can be collected if the person can either climb up the stairs to the next floor of the same building or he can jump to the next floor of any of the adjacent buildings.

Example:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: N = 5, M = 2, K = 3,
points = [ [4, 5, 1, 2, 10],
[9, 7, 3, 20, 16],
[ 6, 12, 13, 9, 8] ]
Output: 70
Explanation: Start from building 2. Collect the 9 points in the first floor.
Jump to building 3. Collect the 12 points from the second and 13 points from third floor. (Jump 1)
Jump back to building 2. Collect the 20 points from fourth floor and 16 points in fifth floor. (Jump 2)
Number of jumps made = 2
Number of points collected= 9+12+13+20+16 = 70 points

Input: N = 4, M = 1, K = 3,
points = [ [7, 5, 4, 10],
[8, 9, 20, 16],
[ 12, 13, 3, 8] ]
Output: 61

Approach: Given problem can be solved using dynamic programming:

• First we define the state of dp
• dp(i, j, k) state – the maximum number of points that can be collected if the person is at ith floor having made at most j jumps and ended up at kth building
• Then we will define the base cases
• If there is only one floor then the person cannot jump, put the number of points at that location.
• If there are 0 jumps allowed then can choose one of the three building and keep climbing up on the same building.
• so, person can only take points from prev floor of same building and add current points
• Then we will define the transition between states
• if we are on first building then we can:
• come from the first building, one floor down, no jumps
• come from the next building, one floor down, one jump added
• add points stored in building 1 at ith floor for both cases
• If we are on intermediate building then we can:
• come from the previous building, one floor down, one jump added
• come from the current building, one floor down, no jump
• can come from the next building, one floor down, one jump added
• will add points stored in intermediate building at ith floor for all 3 cases
• If we are on last building then we can:
• come from previous building, one floor down, one jump added
• come from last building, one floor down, no jump added
• will add points stored in last building at ith floor for both cases
• For the final answer, return the maximum of points collected over the top floor of all building after engaging in permissible number of jumps.

Below is the implementation of the above approach:

## C++14

 `// C++ implementation for the above approach` `#include ``using` `namespace` `std;` `int` `solve(vector >& a, ``int` `floors,``          ``int` `jumps, ``int` `buildings)``{``    ``/*``     ``dp(i, j, k) represents state of the maximum``     ``number of points that can be collected if``     ``the person is at ith floor having made at``     ``most j jumps and ended up at kth building.``    ``*/``    ``int` `dp[floors + 1][jumps + 1][buildings + 1];` `    ``// Initializing dp with 0``    ``memset``(dp, 0, ``sizeof``(dp));``    ``for` `(``int` `i = 1; i <= floors; i++) {``        ``for` `(``int` `j = 0; j <= jumps; j++) {``            ``for` `(``int` `k = 0; k < buildings; k++) {` `                ``// Base case: first floor``                ``if` `(i == 1) {``                    ``// Cannot jump on ground floor``                    ``// from any other building``                    ``dp[i][j][k] = a[k][i - 1];``                ``}` `                ``// Base case: no jumps allowed``                ``else` `if` `(j == 0) {` `                    ``/* can choose one of the buildings``                    ``and keep climbing up on the``                    ``same building so can only take``                    ``points from prev floor of same``                    ``building and add current points``                 ``*/``                    ``dp[i][j][k] = dp[i - 1][j][k]``                                  ``+ a[k][i - 1];``                ``}` `                ``// transition``                ``else` `{` `                    ``// first building``                    ``if` `(k == 0) {` `                        ``/*``                        ``1)can come from building 1,``                        ``one floor down, no jumps.``                        ``2)can come from building 2,``                        ``one floor down, one jump added.``                        ``add points stored in building 1``                        ``at the ith floor for both cases.``                        ``*/``                        ``dp[i][j][k] = max(dp[i - 1][j][k],``                                          ``dp[i - 1][j - 1][k + 1])``                                      ``+ a[k][i - 1];``                    ``}` `                    ``// Last Building``                    ``else` `if` `(k == buildings - 1) {` `                        ``/*``                       ``1)Can come from building k-1 from``                         ``one floor below, one jump added.``                       ``2)Can come from building k from``                        ``one floor below, no jump added.``                        ``add points stored in building k``                        ``at the ith floor for both cases.``                            ``*/``                        ``dp[i][j][k]``                            ``= max(``                                  ``dp[i - 1][j - 1][k - 1],``                                  ``dp[i - 1][j][k])``                              ``+ a[k][i - 1];``                    ``}` `                    ``// intermediate buildings``                    ``else` `{` `                        ``/*``                        ``1)Can come from the building k-1,``                        ``one floor down, one jump added``                        ``2)Can come from the building k,``                        ``one floor down, no jump``                        ``3)Can come from the building k+1,``                        ``one floor down, one jump added.``                        ``add points stored in building k``                        ``at the ith floor for all 3 cases``                        ``*/``                        ``dp[i][j][k]``                            ``= max(``                                  ``{ dp[i - 1][j - 1][k - 1],``                                    ``dp[i - 1][j][k],``                                    ``dp[i - 1][j - 1][k + 1] })``                              ``+ a[k][i - 1];``                    ``}``                ``}``            ``}``        ``}``    ``}` `    ``// Return the maximum of points collected``    ``// over the top floor of all building after``    ``// engaging in permissible number of jumps``    ``int` `ans = 0;``    ``for` `(``int` `building = 0; building < buildings; building++)``        ``ans = max(ans, dp[floors][jumps][building]);` `    ``return` `ans;``}` `// Driver code``int` `main()``{``    ``// Number of floors``    ``// and number of jumps allowed.``    ``int` `N = 5, M = 2, K = 3;` `    ``// Number of points``    ``// at each floor of the buildings.``    ``vector > a = {``        ``{ 4, 5, 1, 2, 10 },``        ``{ 9, 7, 3, 20, 16 },``        ``{ 6, 12, 13, 9, 8 }``    ``};` `    ``// Function call``    ``cout << solve(a, N, M, K) << endl;` `    ``return` `0;``}`

## Java

 `// Java implementation for the above approach``import` `java.util.*;` `class` `GFG``{` `  ``static` `int` `solve(``int``[][] a, ``int` `floors,``                   ``int` `jumps, ``int` `buildings)``  ``{``    ``/*``     ``dp(i, j, k) represents state of the maximum``     ``number of points that can be collected if``     ``the person is at ith floor having made at``     ``most j jumps and ended up at kth building.``    ``*/``    ``int` `[][][]dp = ``new` `int``[floors + ``1``][jumps + ``1``][buildings + ``1``];` `    ``for` `(``int` `i = ``1``; i <= floors; i++) {``      ``for` `(``int` `j = ``0``; j <= jumps; j++) {``        ``for` `(``int` `k = ``0``; k < buildings; k++) {` `          ``// Base case: first floor``          ``if` `(i == ``1``) {``            ``// Cannot jump on ground floor``            ``// from any other building``            ``dp[i][j][k] = a[k][i - ``1``];``          ``}` `          ``// Base case: no jumps allowed``          ``else` `if` `(j == ``0``) {` `            ``/* can choose one of the buildings``                    ``and keep climbing up on the``                    ``same building so can only take``                    ``points from prev floor of same``                    ``building and add current points``                 ``*/``            ``dp[i][j][k] = dp[i - ``1``][j][k]``              ``+ a[k][i - ``1``];``          ``}` `          ``// transition``          ``else` `{` `            ``// first building``            ``if` `(k == ``0``) {` `              ``/*``                        ``1)can come from building 1,``                        ``one floor down, no jumps.``                        ``2)can come from building 2,``                        ``one floor down, one jump added.``                        ``add points stored in building 1``                        ``at the ith floor for both cases.``                        ``*/``              ``dp[i][j][k] = Math.max(dp[i - ``1``][j][k],``                                     ``dp[i - ``1``][j - ``1``][k + ``1``])``                ``+ a[k][i - ``1``];``            ``}` `            ``// Last Building``            ``else` `if` `(k == buildings - ``1``) {` `              ``/*``                       ``1)Can come from building k-1 from``                         ``one floor below, one jump added.``                       ``2)Can come from building k from``                        ``one floor below, no jump added.``                        ``add points stored in building k``                        ``at the ith floor for both cases.``                            ``*/``              ``dp[i][j][k]``                ``= Math.max(``                ``dp[i - ``1``][j - ``1``][k - ``1``],``                ``dp[i - ``1``][j][k])``                ``+ a[k][i - ``1``];``            ``}` `            ``// intermediate buildings``            ``else` `{` `              ``/*``                        ``1)Can come from the building k-1,``                        ``one floor down, one jump added``                        ``2)Can come from the building k,``                        ``one floor down, no jump``                        ``3)Can come from the building k+1,``                        ``one floor down, one jump added.``                        ``add points stored in building k``                        ``at the ith floor for all 3 cases``                        ``*/``              ``dp[i][j][k]``                ``= Math.max(``                ``Math.max( dp[i - ``1``][j - ``1``][k - ``1``],``                         ``dp[i - ``1``][j][k]),``                ``dp[i - ``1``][j - ``1``][k + ``1``] )``                ``+ a[k][i - ``1``];``            ``}``          ``}``        ``}``      ``}``    ``}` `    ``// Return the maximum of points collected``    ``// over the top floor of all building after``    ``// engaging in permissible number of jumps``    ``int` `ans = ``0``;``    ``for` `(``int` `building = ``0``; building < buildings; building++)``      ``ans = Math.max(ans, dp[floors][jumps][building]);` `    ``return` `ans;``  ``}` `  ``// Driver code``  ``public` `static` `void` `main(String[] args)``  ``{``    ` `    ``// Number of floors``    ``// and number of jumps allowed.``    ``int` `N = ``5``, M = ``2``, K = ``3``;` `    ``// Number of points``    ``// at each floor of the buildings.``    ``int``[][] a = {``      ``{ ``4``, ``5``, ``1``, ``2``, ``10` `},``      ``{ ``9``, ``7``, ``3``, ``20``, ``16` `},``      ``{ ``6``, ``12``, ``13``, ``9``, ``8` `}``    ``};` `    ``// Function call``    ``System.out.print(solve(a, N, M, K) +``"\n"``);` `  ``}``}` `// This code is contributed by Princi Singh`

## Python3

 `# Python 3 implementation for the above approach` `def` `solve(a, floors, jumps, buildings):``  ` `    ``#dp(i, j, k) represents state of the maximum``    ``#number of points that can be collected if``    ``#the person is at ith floor having made at``    ``#most j jumps and ended up at kth building.``    ``dp ``=` `[[[``0` `for` `i ``in` `range``(buildings ``+` `1``)] ``for` `j ``in` `range``(jumps ``+` `1``)] ``for` `k ``in` `range``(floors ``+` `1``)]` `    ``for` `i ``in` `range``(``1``, floors ``+` `1``, ``1``):``        ``for` `j ``in` `range``(``0``, jumps ``+` `1``, ``1``):``            ``for` `k ``in` `range``(buildings):``              ` `                ``# Base case: first floor``                ``if` `(i ``=``=` `1``):``                  ` `                    ``# Cannot jump on ground floor``                    ``# from any other building``                    ``dp[i][j][k] ``=` `a[k][i ``-` `1``]` `                ``# Base case: no jumps allowed``                ``elif``(j ``=``=` `0``):``                  ` `                    ``# can choose one of the buildings``                    ``# and keep climbing up on the``                    ``# same building so can only take``                    ``# points from prev floor of same``                    ``# building and add current points``                    ``dp[i][j][k] ``=` `dp[i ``-` `1``][j][k] ``+` `a[k][i ``-` `1``]` `                ``# transition``                ``else``:` `                    ``# first building``                    ``if` `(k ``=``=` `0``):``                        ``# 1)can come from building 1,``                        ``# one floor down, no jumps.``                        ``# 2)can come from building 2,``                        ``# one floor down, one jump added.``                        ``# add points stored in building 1``                        ``# at the ith floor for both cases.``                        ``dp[i][j][k] ``=` `max``(dp[i ``-` `1``][j][k], dp[i ``-` `1``][j ``-` `1``][k ``+` `1``]) ``+` `a[k][i ``-` `1``]` `                    ``# Last Building``                    ``elif``(k ``=``=` `buildings ``-` `1``):``                        ``# 1)Can come from building k-1 from``                        ``# one floor below, one jump added.``                        ``# 2)Can come from building k from``                        ``# one floor below, no jump added.``                        ``# add points stored in building k``                        ``# at the ith floor for both cases.``                        ``dp[i][j][k] ``=` `max``(dp[i ``-` `1``][j ``-` `1``][k ``-` `1``],dp[i ``-` `1``][j][k]) ``+` `a[k][i ``-` `1``]` `                    ``# intermediate buildings``                    ``else``:``                        ``# 1)Can come from the building k-1,``                        ``# one floor down, one jump added``                        ``# 2)Can come from the building k,``                        ``# one floor down, no jump``                        ``# 3)Can come from the building k+1,``                        ``# one floor down, one jump added.``                        ``# add points stored in building k``                        ``# at the ith floor for all 3 cases``                        ``dp[i][j][k] ``=` `max``([dp[i ``-` `1``][j ``-` `1``][k ``-` `1``],dp[i ``-` `1``][j][k],dp[i ``-` `1``][j ``-` `1``][k ``+` `1``]])``+` `a[k][i ``-` `1``]` `    ``# Return the maximum of points collected``    ``# over the top floor of all building after``    ``# engaging in permissible number of jumps``    ``ans ``=` `0``    ``for` `temp ``in` `range``(buildings):``        ``ans ``=` `max``(ans, dp[floors][jumps][temp])` `    ``return` `ans` `# Driver code``if` `__name__ ``=``=` `'__main__'``:``  ` `    ``# Number of floors``    ``# and number of jumps allowed.``    ``N ``=` `5``    ``M ``=` `2``    ``K ``=` `3` `    ``# Number of points``    ``# at each floor of the buildings.``    ``a ``=` `[[``4``, ``5``, ``1``, ``2``, ``10``],``         ``[``9``, ``7``, ``3``, ``20``, ``16``],``         ``[``6``, ``12``, ``13``, ``9``, ``8``]]` `    ``# Function call``    ``print``(solve(a, N, M, K))``    ` `    ``# This code is contributed by ipg2016107.`

## C#

 `// C# implementation for the above approach``using` `System;` `class` `GFG``{` `  ``static` `int` `solve(``int``[,] a, ``int` `floors,``                   ``int` `jumps, ``int` `buildings)``  ``{``    ``/*``     ``dp(i, j, k) represents state of the maximum``     ``number of points that can be collected if``     ``the person is at ith floor having made at``     ``most j jumps and ended up at kth building.``    ``*/``    ``int` `[,,]dp = ``new` `int``[floors + 1,jumps + 1,buildings + 1];` `    ``for` `(``int` `i = 1; i <= floors; i++) {``      ``for` `(``int` `j = 0; j <= jumps; j++) {``        ``for` `(``int` `k = 0; k < buildings; k++) {` `          ``// Base case: first floor``          ``if` `(i == 1)``          ``{``            ` `            ``// Cannot jump on ground floor``            ``// from any other building``            ``dp[i, j, k] = a[k, i - 1];``          ``}` `          ``// Base case: no jumps allowed``          ``else` `if` `(j == 0) {` `            ``/* can choose one of the buildings``                    ``and keep climbing up on the``                    ``same building so can only take``                    ``points from prev floor of same``                    ``building and add current points``                 ``*/``            ``dp[i, j, k] = dp[i - 1, j, k]``              ``+ a[k, i - 1];``          ``}` `          ``// transition``          ``else` `{` `            ``// first building``            ``if` `(k == 0) {` `              ``/*``                        ``1)can come from building 1,``                        ``one floor down, no jumps.``                        ``2)can come from building 2,``                        ``one floor down, one jump added.``                        ``add points stored in building 1``                        ``at the ith floor for both cases.``                        ``*/``              ``dp[i, j, k] = Math.Max(dp[i - 1, j, k],``                                     ``dp[i - 1, j - 1, k + 1])``                ``+ a[k,i - 1];``            ``}` `            ``// Last Building``            ``else` `if` `(k == buildings - 1) {` `              ``/*``                       ``1)Can come from building k-1 from``                         ``one floor below, one jump added.``                       ``2)Can come from building k from``                        ``one floor below, no jump added.``                        ``add points stored in building k``                        ``at the ith floor for both cases.``                            ``*/``              ``dp[i, j, k]``                ``= Math.Max(``                ``dp[i - 1,j - 1,k - 1],``                ``dp[i - 1,j,k])``                ``+ a[k,i - 1];``            ``}` `            ``// intermediate buildings``            ``else` `{` `              ``/*``                        ``1)Can come from the building k-1,``                        ``one floor down, one jump added``                        ``2)Can come from the building k,``                        ``one floor down, no jump``                        ``3)Can come from the building k+1,``                        ``one floor down, one jump added.``                        ``add points stored in building k``                        ``at the ith floor for all 3 cases``                        ``*/``              ``dp[i, j, k]``                ``= Math.Max(``                ``Math.Max( dp[i - 1, j - 1, k - 1],``                         ``dp[i - 1, j, k]),``                ``dp[i - 1, j - 1, k + 1] )``                ``+ a[k, i - 1];``            ``}``          ``}``        ``}``      ``}``    ``}` `    ``// Return the maximum of points collected``    ``// over the top floor of all building after``    ``// engaging in permissible number of jumps``    ``int` `ans = 0;``    ``for` `(``int` `building = 0; building < buildings; building++)``      ``ans = Math.Max(ans, dp[floors,jumps,building]);` `    ``return` `ans;``  ``}` `  ``// Driver code``  ``public` `static` `void` `Main(``string``[] args)``  ``{``    ` `    ``// Number of floors``    ``// and number of jumps allowed.``    ``int` `N = 5, M = 2, K = 3;` `    ``// Number of points``    ``// at each floor of the buildings.``    ``int``[,] a = {``      ``{ 4, 5, 1, 2, 10 },``      ``{ 9, 7, 3, 20, 16 },``      ``{ 6, 12, 13, 9, 8 }``    ``};` `    ``// Function call``    ``Console.WriteLine(solve(a, N, M, K));` `  ``}``}` `// This code is contributed by AnkThon`

## Javascript

 ``
Output:
`70`

Time Complexity: O(N*M*K) which means O(floors*jumps*buildings)
Auxiliary Space: O(N*M*K) which means O(floors*jumps*buildings)

My Personal Notes arrow_drop_up