Consider a game, in which you have two types of powers, A and B and there are 3 types of Areas X, Y and Z. Every second you have to switch between these areas, each area has specific properties by which your power A and power B increase or decrease. We need to keep choosing areas in such a way that our survival time is maximized. Survival time ends when any of the powers, A or B reaches less than 0.

Examples:

Initial value of Power A = 20 Initial value of Power B = 8 Area X (3, 2) : If you step into Area X, A increases by 3, B increases by 2 Area Y (-5, -10) : If you step into Area Y, A decreases by 5, B decreases by 10 Area Z (-20, 5) : If you step into Area Z, A decreases by 20, B increases by 5 It is possible to choose any area in our first step. We can survive at max 5 unit of time by following these choice of areas : X -> Z -> X -> Y -> X

This problem can be solved using recursion, after each time unit we can go to any of the area but we will choose that area which ultimately leads to maximum survival time. As recursion can lead to solving same subproblem many time, we will memoize the result on basis of power A and B, if we reach to same pair of power A and B, we won’t solve it again instead we will take the previously calculated result.

Given below is the simple implementation of above approach.

## CPP

`// C++ code to get maximum survival time ` `#include <bits/stdc++.h> ` `using` `namespace` `std; ` ` ` `// structure to represent an area ` `struct` `area ` `{ ` ` ` `// increment or decrement in A and B ` ` ` `int` `a, b; ` ` ` `area(` `int` `a, ` `int` `b) : a(a), b(b) ` ` ` `{} ` `}; ` ` ` `// Utility method to get maximum of 3 integers ` `int` `max(` `int` `a, ` `int` `b, ` `int` `c) ` `{ ` ` ` `return` `max(a, max(b, c)); ` `} ` ` ` `// Utility method to get maximum survival time ` `int` `maxSurvival(` `int` `A, ` `int` `B, area X, area Y, area Z, ` ` ` `int` `last, map<pair<` `int` `, ` `int` `>, ` `int` `>& memo) ` `{ ` ` ` `// if any of A or B is less than 0, return 0 ` ` ` `if` `(A <= 0 || B <= 0) ` ` ` `return` `0; ` ` ` `pair<` `int` `, ` `int` `> cur = make_pair(A, B); ` ` ` ` ` `// if already calculated, return calculated value ` ` ` `if` `(memo.find(cur) != memo.end()) ` ` ` `return` `memo[cur]; ` ` ` ` ` `int` `temp; ` ` ` ` ` `// step to areas on basis of last chose area ` ` ` `switch` `(last) ` ` ` `{ ` ` ` `case` `1: ` ` ` `temp = 1 + max(maxSurvival(A + Y.a, B + Y.b, ` ` ` `X, Y, Z, 2, memo), ` ` ` `maxSurvival(A + Z.a, B + Z.b, ` ` ` `X, Y, Z, 3, memo)); ` ` ` `break` `; ` ` ` `case` `2: ` ` ` `temp = 1 + max(maxSurvival(A + X.a, B + X.b, ` ` ` `X, Y, Z, 1, memo), ` ` ` `maxSurvival(A + Z.a, B + Z.b, ` ` ` `X, Y, Z, 3, memo)); ` ` ` `break` `; ` ` ` `case` `3: ` ` ` `temp = 1 + max(maxSurvival(A + X.a, B + X.b, ` ` ` `X, Y, Z, 1, memo), ` ` ` `maxSurvival(A + Y.a, B + Y.b, ` ` ` `X, Y, Z, 2, memo)); ` ` ` `break` `; ` ` ` `} ` ` ` ` ` `// store the result into map ` ` ` `memo[cur] = temp; ` ` ` ` ` `return` `temp; ` `} ` ` ` `// method returns maximum survival time ` `int` `getMaxSurvivalTime(` `int` `A, ` `int` `B, area X, area Y, area Z) ` `{ ` ` ` `if` `(A <= 0 || B <= 0) ` ` ` `return` `0; ` ` ` `map< pair<` `int` `, ` `int` `>, ` `int` `> memo; ` ` ` ` ` `// At first, we can step into any of the area ` ` ` `return` ` ` `max(maxSurvival(A + X.a, B + X.b, X, Y, Z, 1, memo), ` ` ` `maxSurvival(A + Y.a, B + Y.b, X, Y, Z, 2, memo), ` ` ` `maxSurvival(A + Z.a, B + Z.b, X, Y, Z, 3, memo)); ` `} ` ` ` `// Driver code to test above method ` `int` `main() ` `{ ` ` ` `area X(3, 2); ` ` ` `area Y(-5, -10); ` ` ` `area Z(-20, 5); ` ` ` ` ` `int` `A = 20; ` ` ` `int` `B = 8; ` ` ` `cout << getMaxSurvivalTime(A, B, X, Y, Z); ` ` ` ` ` `return` `0; ` `} ` |

*chevron_right*

*filter_none*

## Python3

`# Python code to get maximum survival time ` ` ` `# Class to represent an area ` `class` `area: ` ` ` `def` `__init__(` `self` `, a, b): ` ` ` `self` `.a ` `=` `a ` ` ` `self` `.b ` `=` `b ` ` ` `# Utility method to get maximum survival time ` `def` `maxSurvival(A, B, X, Y, Z, last, memo): ` ` ` `# if any of A or B is less than 0, return 0 ` ` ` `if` `(A <` `=` `0` `or` `B <` `=` `0` `): ` ` ` `return` `0` ` ` `cur ` `=` `area(A, B) ` ` ` ` ` `# if already calculated, return calculated value ` ` ` `for` `ele ` `in` `memo.keys(): ` ` ` `if` `(cur.a ` `=` `=` `ele.a ` `and` `cur.b ` `=` `=` `ele.b): ` ` ` `return` `memo[ele] ` ` ` ` ` `# step to areas on basis of last chosen area ` ` ` `if` `(last ` `=` `=` `1` `): ` ` ` `temp ` `=` `1` `+` `max` `(maxSurvival(A ` `+` `Y.a, B ` `+` `Y.b, ` ` ` `X, Y, Z, ` `2` `, memo), ` ` ` `maxSurvival(A ` `+` `Z.a, B ` `+` `Z.b, ` ` ` `X, Y, Z, ` `3` `, memo)) ` ` ` `elif` `(last ` `=` `=` `2` `): ` ` ` `temp ` `=` `1` `+` `max` `(maxSurvival(A ` `+` `X.a, B ` `+` `X.b, ` ` ` `X, Y, Z, ` `1` `, memo), ` ` ` `maxSurvival(A ` `+` `Z.a, B ` `+` `Z.b, ` ` ` `X, Y, Z, ` `3` `, memo)) ` ` ` `elif` `(last ` `=` `=` `3` `): ` ` ` `temp ` `=` `1` `+` `max` `(maxSurvival(A ` `+` `X.a, B ` `+` `X.b, ` ` ` `X, Y, Z, ` `1` `, memo), ` ` ` `maxSurvival(A ` `+` `Y.a, B ` `+` `Y.b, ` ` ` `X, Y, Z, ` `2` `, memo)) ` ` ` ` ` `# store the result into map ` ` ` `memo[cur] ` `=` `temp ` ` ` ` ` `return` `temp ` ` ` `# method returns maximum survival time ` `def` `getMaxSurvivalTime(A, B, X, Y, Z): ` ` ` `if` `(A <` `=` `0` `or` `B <` `=` `0` `): ` ` ` `return` `0` ` ` `memo ` `=` `dict` `() ` ` ` ` ` `# At first, we can step into any of the area ` ` ` `return` `max` `(maxSurvival(A ` `+` `X.a, B ` `+` `X.b, X, Y, Z, ` `1` `, memo), ` ` ` `maxSurvival(A ` `+` `Y.a, B ` `+` `Y.b, X, Y, Z, ` `2` `, memo), ` ` ` `maxSurvival(A ` `+` `Z.a, B ` `+` `Z.b, X, Y, Z, ` `3` `, memo)) ` ` ` `# Driver code to test above method ` `X ` `=` `area(` `3` `, ` `2` `) ` `Y ` `=` `area(` `-` `5` `, ` `-` `10` `) ` `Z ` `=` `area(` `-` `20` `, ` `5` `) ` ` ` `A ` `=` `20` `B ` `=` `8` `print` `(getMaxSurvivalTime(A, B, X, Y, Z)) ` ` ` `# This code is contributed by Soumen Ghosh. ` |

*chevron_right*

*filter_none*

Output:

5

This article is contributed by **Utkarsh Trivedi**. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

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.

## Recommended Posts:

- Maximum value with the choice of either dividing or considering as it is
- Largest area rectangular sub-matrix with equal number of 1's and 0's
- Maximum sub-matrix area having count of 1's one more than count of 0's
- Find the largest area rectangular sub-matrix whose sum is equal to k
- Count minimum number of moves to front or end to sort an array
- Maximum subsequence sum such that no K elements are consecutive
- Count possible splits of sum N into K integers such that the minimum is at least P
- Paths requiring minimum number of jumps to reach end of array
- Length of longest increasing absolute even subsequence
- Count N digits numbers with sum divisible by K
- Maximize length of longest increasing prime subsequence from the given array
- Longest increasing subsequence which forms a subarray in the sorted representation of the array
- Maximum score assigned to a subsequence of numerically consecutive and distinct array elements
- Maximum subsequence sum possible by multiplying each element by its index