Given a matrix of size rows x cols called “power,” which represents the power associated with each cell in the field. There are two types of current flow in the field: “+” current starts from the top left corner, while “-” current starts from the top right corner. Both types of current can move in three directions: from a cell (i, j) to either (i + 1, j – 1), (i + 1, j), or (i + 1, j + 1). The power consumption between two cells is calculated as the absolute difference between the power values of the two cells: abs(power[i + 1][j + 1] – power[i][j]). The task is to calculate the minimum total power consumption by both the current “+” & “-” to reach the last row.
Note: At any given point (i, j), both types of current cannot occupy the same cell simultaneously, as it would cause an electric shock.
Examples:
Input: power[][] = {{2, 4}, {3, 9}}
Output: combined minimum power : 6
Explanation: The “+” current chooses the path 2 -> 3, and the “-” current chooses the path 4 -> 9. The minimum total power consumption [abs(3 – 2) + abs(9 – 4)] = 1 + 5 = 6Input: power[][] = {{2, 4, 6}, {8, 0, 10}, {6, 3, 9}}
Output: combined minimum power : 10
Explanation: The “+” current chooses the path 2 -> 0-> 3, and the “-” current chooses the path 6->10-> 9. The minimum total power consumption [abs(0 – 2) + abs(3 – 0) + abs(10 – 6) + abs(9 – 10)] = 5 + 5= 10.
Approach: To solve the problem using Recursion follow the below idea:
- As mentioned in the question, both “+” and “-” currents can move in three directions: (i + 1, j – 1), (i + 1, j), or (i + 1, j + 1). Therefore, the total combined directions will be 3 * 3 = 9. For each “+” current, there will be three possible ways for the “-” current to move. We need to consider all the possible 9 directions.
- The base case occurs when both the “+” and “-” currents reach the last row, which will be the minimum valid position. Once they reach the last row, it becomes the base case.
- Now, for all possible paths, we calculate the minimum and return it as the result.
Mathematically the recursion will look like the following:
- value = abs(power[next_i][next_j1] – power[i][j1]) + abs(power[next_i][next_J2] – power[i][j2]);
- value += totalPower(next_i, next_j1, next_j2, power, rows, cols);
- mini = min(mini, value);
- // base case { once it reaches to last row. }
- i == power.size()-1;
Steps to solve the problem:
- Build a recursive function and pass the starting row, col for both the current.
- For each (i, j) check if it’s valid or not, if it’s valid store the power consumption and call recursion for next.
- compare all the paths and take out the minimum power consumption.
Below is the implementation for the above approach:
C++
// C++ code for the above approach:#include <bits/stdc++.h>using namespace std;int totalPower(int i, int j1, int j2, int power[][3], int rows, int cols){ // Base case: both "+" and "-" // reach the last row if (i == rows - 1) return 0; int mini = INT_MAX; // At each (i, j), there are 9 // combined possibilities 3 possibilities // for j1 (from -1 to 1), and the same // for j2 Thus, a total of 3 * 3 // possibilities for (int k = -1; k <= 1; k++) { for (int p = -1; p <= 1; p++) { int nextI = i + 1; int nextJ1 = j1 + k; int nextJ2 = j2 + p; // Check the validity of the // path and ensure there // is no collision if (nextI >= 0 && nextI < rows && nextJ1 >= 0 && nextJ1 < cols && nextJ2 >= 0 && nextJ2 < cols && nextJ1 != nextJ2) { int value = abs(power[nextI][nextJ1] - power[i][j1]) + abs(power[nextI][nextJ2] - power[i][j2]); // Recursively call for // the next i, j1, and j2 value += totalPower(nextI, nextJ1, nextJ2, power, rows, cols); // Take the minimum mini = min(mini, value); } } } // return the answer return mini;}// Driver codeint main(){ int power[][3] = { { 2, 4, 6 }, { 8, 0, 10 }, { 6, 3, 9 } }; int rows = sizeof(power) / sizeof(power[0]); int cols = sizeof(power[0]) / sizeof(power[0][0]); // Function call cout << "Combined Minimum Power: " << totalPower(0, 0, cols - 1, power, rows, cols) << endl; return 0;} |
Java
// Java code for the above approachimport java.util.*;class GFG { static int totalPower(int i, int j1, int j2, int power[][], int rows, int cols) { // Base case: both "+" and "-" // reach the last row if (i == rows - 1) return 0; int mini = Integer.MAX_VALUE; // At each (i, j), there are 9 // combined possibilities 3 possibilities // for j1 (from -1 to 1), and the same // for j2 Thus, a total of 3 * 3 // possibilities for (int k = -1; k <= 1; k++) { for (int p = -1; p <= 1; p++) { int nextI = i + 1; int nextJ1 = j1 + k; int nextJ2 = j2 + p; // Check the validity of the // path and ensure there // is no collision if (nextI >= 0 && nextI < rows && nextJ1 >= 0 && nextJ1 < cols && nextJ2 >= 0 && nextJ2 < cols && nextJ1 != nextJ2) { int value = Math.abs(power[nextI][nextJ1] - power[i][j1]) + Math.abs(power[nextI][nextJ2] - power[i][j2]); // Recursively call for // the next i, j1, and j2 value += totalPower(nextI, nextJ1, nextJ2, power, rows, cols); // Take the minimum mini = Math.min(mini, value); } } } // return the answer return mini; } // Driver code public static void main(String[] args) { int power[][] = { { 2, 4, 6 }, { 8, 0, 10 }, { 6, 3, 9 } }; int rows = power.length; int cols = power[0].length; // Function call System.out.println("Combined Minimum Power: " + totalPower(0, 0, cols - 1, power, rows, cols)); }}// This code is contributed by Tapesh(tapeshdua420) |
Python3
def totalPower(i, j1, j2, power, rows, cols): # Base case: both "+" and "-" reach the last row if i == rows - 1: return 0 mini = float('inf') # At each (i, j), there are 9 combined possibilities # 3 possibilities for j1 (from -1 to 1), and the same for j2 # Thus, a total of 3 * 3 possibilities for k in range(-1, 2): for p in range(-1, 2): nextI = i + 1 nextJ1 = j1 + k nextJ2 = j2 + p # Check the validity of the path and ensure there is no collision if ( 0 <= nextI < rows and 0 <= nextJ1 < cols and 0 <= nextJ2 < cols and nextJ1 != nextJ2 ): value = ( abs(power[nextI][nextJ1] - power[i][j1]) + abs(power[nextI][nextJ2] - power[i][j2]) ) # Recursively call for the next i, j1, and j2 value += totalPower(nextI, nextJ1, nextJ2, power, rows, cols) # Take the minimum mini = min(mini, value) # return the answer return mini# Driver codeif __name__ == "__main__": power = [[2, 4, 6], [8, 0, 10], [6, 3, 9]] rows = len(power) cols = len(power[0]) # Function call print("Combined Minimum Power:", totalPower(0, 0, cols - 1, power, rows, cols))#This code is Contributed by chinmaya121221 |
Combined Minimum Power: 10
Complexity Analysis:
- Time Complexity: O(3n + 3n) The above solution may try all the possiable path in worst case. Therefore time complexity of the above solution is exponential.
- Auxiliary Space: O(n) where n is recursion stack space.
Using Memoization :
Each state of the solution can be uniquely identified using three variables – rows,col1 & col2 (for both “+” and “-“) . So create a 3D array to store the value of each state to avoid recalculation of the same state.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>using namespace std;int columns = 0;int totalPower(int i, int j1, int j2, int power[][3], int rows, int cols, int memo[][3][3]) { // Base case: both "+" and "-" reach the last row if (i == rows - 1) return 0; // Check if the value is already calculated and stored in memo if (memo[i][j1][j2] != -1) return memo[i][j1][j2]; int mini = INT_MAX; // At each (i, j), there are 9 combined possibilities // 3 possibilities for j1 (from -1 to 1), and the same for j2 // Thus, a total of 3 * 3 possibilities for (int k = -1; k <= 1; k++) { for (int p = -1; p <= 1; p++) { int nextI = i + 1; int nextJ1 = j1 + k; int nextJ2 = j2 + p; // Check the validity of the path and ensure there is no collision if (nextI >= 0 && nextI < rows && nextJ1 >= 0 && nextJ1 < cols && nextJ2 >= 0 && nextJ2 < cols && nextJ1 != nextJ2) { int value = abs(power[nextI][nextJ1] - power[i][j1]) + abs(power[nextI][nextJ2] - power[i][j2]); // Recursively call for the next i, j1, and j2 value += totalPower(nextI, nextJ1, nextJ2, power, rows, cols, memo); // Take the minimum mini = min(mini, value); } } } // Store the calculated value in memo memo[i][j1][j2] = mini; // Return the answer return mini;}// Driver codeint main() { int power[][3] = {{2, 4, 6}, {8, 0, 10}, {6, 3, 9}}; int rows = sizeof(power) / sizeof(power[0]); int cols = sizeof(power[0]) / sizeof(power[0][0]); columns = cols; int memo[rows][3][3]; memset(memo, -1, sizeof(memo)); // Initialize memo with -1 cout << "Combined Minimum Power: " << totalPower(0, 0, cols - 1, power, rows, cols, memo) << endl; return 0;} |
Combined Minimum Power: 10
Complexity Analysis:
- Time Complexity: The time complexity of the given solution is O(N3), where N represents the number of columns in the power matrix. This is because, at each cell (i, j1, j2), we iterate over all possible combinations of j1 and j2.
- Auxiliary Space: The space complexity of the given solution is O(N3) as well. This is because we use a 3D array
memoto store the calculated values for each state (i, j1, j2), resulting in a space requirement of O(N3).
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!
