Minimum Initial Points to Reach Destination

Last Updated : 17 Apr, 2024

Given a M*N grid with each cell consisting of positive, negative, or no points i.e., zero points. From a cell (i, j) we can move to (i+1, j) or (i, j+1) and we can move to a cell only if we have positive points ( > 0 ) when we move to that cell. Whenever we pass through a cell, points in that cell are added to our overall points. We need to find minimum initial points to reach cell (m-1, n-1) from (0, 0).

Example:

Input: M = 3, N = 3, points[][] = {{-2,-3,3}, {-5,-10,1}, {10,30,-5}}
Output: 7
Explanation: 7 is the minimum value to reach the destination with positive throughout the path. Below is the path (0,0) -> (0,1) -> (0,2) -> (1, 2) -> (2, 2). We start from (0, 0) with 7, we reach (0, 1) with 5, (0, 2) with 2, (1, 2) with 5, (2, 2) with and finally we have 1 point (we needed greater than 0 points at the end).

Input: M = 3, N = 2, points[][] = {{2,3}, {5,10}, {10,30}}
Output: 1
Explanation: Take any path, all of them are positive. So, required one point at the start

Minimum Initial Points to Reach Destination using Dynamic Programming:

We can solve this problem through bottom-up table filling dynamic programming technique.

The idea is to use a 2D dp array where dp[i][j] represents the minimum initial points required to reach destination cell (m-1,n-1) starting from cell (i,j). From any cell (i,j) there two options to move (i+1,j) and (i,j+1), so to compute dp[i][j], we choose a cell that require less intial points to reach the end i.e., min(dp[i+1][j], dp[i][j+1]).

Follow the steps to solve the problem

• Create a 2D dp array of the same size as the grid, where dp[i][j] represents the minimum initial points required to reach destination cell (m-1,n-1) starting from cell (i,j). dp[0][0] is our final answer.
• Start filling the array from the bottom right corner to left top.
• At any cell (i,j) there two options to move (i-1,j) and (i,j-1). We choose a cell that require less initial points to reach the end i.e., min_Points_on_exit = min(dp[i-1][j], dp[i][j-1]) min(dp[i-1][j], dp[i][j-1]). From min_Points_on_exit we can compute dp[i][j] by:-

dp[i][j] = max(min_Points_on_exit â€“ points[i][j], 1)

How the above expression covers all the cases?

1. If points[i][j] == 0, then nothing is gained in this cell;we leave the cell with the same points as we enter the cell with, i.e. dp[i][j] = min_Points_on_exit.
2. If points[i][j] < 0, then the we must have points greater than min_Points_on_exit before entering (i, j) in order to compensate for the points lost in this cell. The minimum amount of compensation is ” – points[i][j] “, so we have dp[i][j] = min_Points_on_exit – points[i][j].
3. If points[i][j] > 0, then we could enter (i, j) with points as little as min_Points_on_exit – points[i][j]. since we could gain “points[i][j]” points in this cell. However, the value of min_Points_on_exit – points[i][j] might drop to 0 or below in this situation. When this happens, we must increase the value to 1 in order to make sure dp[i][j] stays positive: dp[i][j] = max(min_Points_on_exit – points[i][j], 1).

Below is the implementation of above algorithm.

Java ```import java.io.*; import java.util.*; class min_steps { static int minInitialPoints(int points[][], int R, int C) { // dp[i][j] represents the minimum initial points // player should have so that when starts with // cell(i, j) successfully reaches the destination // cell(m-1, n-1) int dp[][] = new int[R][C]; int m = R, n = C; // Base case dp[m - 1][n - 1] = points[m - 1][n - 1] > 0 ? 1 : Math.abs(points[m - 1][n - 1]) + 1; // Fill last row and last column as base to fill // entire table for (int i = m - 2; i >= 0; i--) dp[i][n - 1] = Math.max( dp[i + 1][n - 1] - points[i][n - 1], 1); for (int j = n - 2; j >= 0; j--) dp[m - 1][j] = Math.max( dp[m - 1][j + 1] - points[m - 1][j], 1); // fill the table in bottom-up fashion for (int i = m - 2; i >= 0; i--) { for (int j = n - 2; j >= 0; j--) { int min_points_on_exit = Math.min(dp[i + 1][j], dp[i][j + 1]); dp[i][j] = Math.max( min_points_on_exit - points[i][j], 1); } } return dp[0][0]; } /* Driver program to test above function */ public static void main(String args[]) { int points[][] = { { -2, -3, 3 }, { -5, -10, 1 }, { 10, 30, -5 } }; int R = 3, C = 3; System.out.println( "Minimum Initial Points Required: " + minInitialPoints(points, R, C)); } } /* This code is contributed by Rajat Mishra */ ``` Python3 ```# Python3 program to find minimum initial # points to reach destination import math as mt R = 3 C = 3 def minInitialPoints(points): ''' dp[i][j] represents the minimum initial points player should have so that when starts with cell(i, j) successfully reaches the destination cell(m-1, n-1) ''' dp = [[0 for x in range(C + 1)] for y in range(R + 1)] m, n = R, C if points[m - 1][n - 1] > 0: dp[m - 1][n - 1] = 1 else: dp[m - 1][n - 1] = abs(points[m - 1][n - 1]) + 1 ''' Fill last row and last column as base to fill entire table ''' for i in range(m - 2, -1, -1): dp[i][n - 1] = max(dp[i + 1][n - 1] - points[i][n - 1], 1) for i in range(n - 2, -1, -1): dp[m - 1][i] = max(dp[m - 1][i + 1] - points[m - 1][i], 1) ''' fill the table in bottom-up fashion ''' for i in range(m - 2, -1, -1): for j in range(n - 2, -1, -1): min_points_on_exit = min(dp[i + 1][j], dp[i][j + 1]) dp[i][j] = max(min_points_on_exit - points[i][j], 1) return dp[0][0] # Driver code points = [[-2, -3, 3], [-5, -10, 1], [10, 30, -5]] print("Minimum Initial Points Required:", minInitialPoints(points)) # This code is contributed by # Mohit kumar 29 (IIIT gwalior) ``` C# ```// C# program Minimum Initial Points // to Reach Destination using System; class GFG { static int minInitialPoints(int[, ] points, int R, int C) { // dp[i][j] represents the // minimum initial points // player should have so // that when starts with // cell(i, j) successfully // reaches the destination // cell(m-1, n-1) int[, ] dp = new int[R, C]; int m = R, n = C; // Base case dp[m - 1, n - 1] = points[m - 1, n - 1] > 0 ? 1 : Math.Abs(points[m - 1, n - 1]) + 1; // Fill last row and last // column as base to fill // entire table for (int i = m - 2; i >= 0; i--) dp[i, n - 1] = Math.Max( dp[i + 1, n - 1] - points[i, n - 1], 1); for (int j = n - 2; j >= 0; j--) dp[m - 1, j] = Math.Max( dp[m - 1, j + 1] - points[m - 1, j], 1); // fill the table in // bottom-up fashion for (int i = m - 2; i >= 0; i--) { for (int j = n - 2; j >= 0; j--) { int min_points_on_exit = Math.Min(dp[i + 1, j], dp[i, j + 1]); dp[i, j] = Math.Max( min_points_on_exit - points[i, j], 1); } } return dp[0, 0]; } // Driver Code public static void Main() { int[, ] points = { { -2, -3, 3 }, { -5, -10, 1 }, { 10, 30, -5 } }; int R = 3, C = 3; Console.Write("Minimum Initial Points Required: " + minInitialPoints(points, R, C)); } } // This code is contributed by nitin mittal. ``` Javascript ```<script> // Javascript program to find minimum initial points to reach destination function minInitialPoints(points,R,C) { // dp[i][j] represents the minimum initial points player // should have so that when starts with cell(i, j) successfully // reaches the destination cell(m-1, n-1) var dp = new Array(R); var m = R, n = C; // Loop to create 2D array using 1D array for (var i = 0; i < dp.length; i++) { dp[i] = new Array(C); } // Base case dp[m-1][n-1] = points[m-1][n-1] > 0? 1: Math.abs(points[m-1][n-1]) + 1; // Fill last row and last column as base to fill // entire table for (var i = m-2; i >= 0; i--) dp[i][n-1] = Math.max(dp[i+1][n-1] - points[i][n-1], 1); for (var j = n-2; j >= 0; j--) dp[m-1][j] = Math.max(dp[m-1][j+1] - points[m-1][j], 1); // fill the table in bottom-up fashion for (var i=m-2; i>=0; i--) { for (var j=n-2; j>=0; j--) { var min_points_on_exit = Math.min(dp[i+1][j], dp[i][j+1]); dp[i][j] = Math.max(min_points_on_exit - points[i][j], 1); } } return dp[0][0]; } var points = [ [-2,-3,3], [-5,-10,1], [10,30,-5] ]; var R = 3,C = 3; document.write("Minimum Initial Points Required: "+minInitialPoints(points,R,C) ); //This code is contributed by shruti456rawal </script> ``` PHP ```<?php // PHP program to find minimum initial // points to reach destination \$R = 3; \$C = 3; function minInitialPoints(\$points) { // dp[i][j] represents the minimum // initial points player should have // so that when starts with cell(i, j) // successfully reaches the destination // cell(m-1, n-1) global \$R; global \$C; \$dp[\$R][\$C] = array(); \$m = \$R; \$n = \$C; // Base case \$dp[\$m - 1][\$n - 1] = \$points[\$m - 1][\$n - 1] > 0 ? 1 : abs(\$points[\$m - 1][\$n - 1]) + 1; // Fill last row and last column as // base to fill entire table for (\$i = \$m - 2; \$i >= 0; \$i--) \$dp[\$i][\$n - 1] = max(\$dp[\$i + 1][\$n - 1] - \$points[\$i][\$n - 1], 1); for (\$j = \$n - 2; \$j >= 0; \$j--) \$dp[\$m - 1][\$j] = max(\$dp[\$m - 1][\$j + 1] - \$points[\$m - 1][\$j], 1); // fill the table in bottom-up fashion for (\$i = \$m - 2; \$i >= 0; \$i--) { for (\$j = \$n - 2; \$j >= 0; \$j--) { \$min_points_on_exit = min(\$dp[\$i + 1][\$j], \$dp[\$i][\$j + 1]); \$dp[\$i][\$j] = max(\$min_points_on_exit - \$points[\$i][\$j], 1); } } return \$dp[0][0]; } // Driver Code \$points = array(array(-2, -3, 3), array(-5, -10, 1), array(10, 30, -5)); echo "Minimum Initial Points Required: ", minInitialPoints(\$points); // This code is contributed by akt_mit ?> ``` C++14 ```// C++ program to find minimum initial points to reach // destination #include <bits/stdc++.h> #define R 3 #define C 3 using namespace std; int minInitialPoints(int points[][C]) { // dp[i][j] represents the minimum initial points player // should have so that when starts with cell(i, j) // successfully reaches the destination cell(m-1, n-1) int dp[R][C]; int m = R, n = C; // Base case dp[m - 1][n - 1] = points[m - 1][n - 1] > 0 ? 1 : abs(points[m - 1][n - 1]) + 1; // Fill last row and last column as base to fill // entire table for (int i = m - 2; i >= 0; i--) dp[i][n - 1] = max(dp[i + 1][n - 1] - points[i][n - 1], 1); for (int j = n - 2; j >= 0; j--) dp[m - 1][j] = max(dp[m - 1][j + 1] - points[m - 1][j], 1); // fill the table in bottom-up fashion for (int i = m - 2; i >= 0; i--) { for (int j = n - 2; j >= 0; j--) { int min_points_on_exit = min(dp[i + 1][j], dp[i][j + 1]); dp[i][j] = max(min_points_on_exit - points[i][j], 1); } } return dp[0][0]; } // Driver Program int main() { int points[R][C] = { { -2, -3, 3 }, { -5, -10, 1 }, { 10, 30, -5 } }; cout << "Minimum Initial Points Required: " << minInitialPoints(points); return 0; } ```

Output
```Minimum Initial Points Required: 7

```

Time Complexity: O(M*N)
Auxiliary Space: O(M*N)

Previous
Next