Choice of Area

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, and 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>usingnamespacestd;//  structure to represent an areastructarea{    //  increment or decrement in A and B    inta, b;    area(inta, intb) : a(a), b(b)    {}};//  Utility method to get maximum of 3 integersintmax(inta, intb, intc){    returnmax(a, max(b, c));}//  Utility method to get maximum survival timeintmaxSurvival(intA, intB, area X, area Y, area Z,                intlast, map<pair<int, int>, int>& memo){    //  if any of A or B is less than 0, return 0    if(A <= 0 || B <= 0)        return0;    pair<int, int> cur = make_pair(A, B);    //  if already calculated, return calculated value    if(memo.find(cur) != memo.end())        returnmemo[cur];    inttemp;    //  step to areas on basis of last choose area    switch(last)    {    case1:        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;    case2:        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;    case3:        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;    returntemp;}//  method returns maximum survival timeintgetMaxSurvivalTime(intA, intB, area X, area Y, area Z){    if(A <= 0 || B <= 0)        return0;    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 methodintmain(){    area X(3, 2);    area Y(-5, -10);    area Z(-20, 5);    intA = 20;    intB = 8;    cout << getMaxSurvivalTime(A, B, X, Y, Z);    return0;} | 
Java
| /*package whatever //do not write package name here */importjava.util.*;importjava.io.*;classGFG {  // Java code to get maximum survival time  // class to represent an area  staticclassarea  {    // increment or decrement in A and B    publicinta, b;    publicarea(inta, intb){      this.a = a;      this.b = b;    }  };  // class to represent pair  staticclassPair{    publicintfirst,second;    publicPair(intfirst,intsecond){      this.first = first;      this.second = second;    }  }  // Utility method to get maximum of 3 integers  staticintmax(inta, intb, intc)  {    returnMath.max(a, Math.max(b, c));  }  // Utility method to get maximum survival time  staticintmaxSurvival(intA, intB, area X, area Y, area Z,                         intlast, HashMap<Pair, Integer> memo)  {    // if any of A or B is less than 0, return 0    if(A <= 0|| B <= 0)      return0;    Pair cur = newPair(A, B);    // if already calculated, return calculated value    if(memo.containsKey(cur))      returnmemo.get(cur);    inttemp = 0;    // step to areas on basis of last choose area    switch(last)    {      case1:        temp = 1+ Math.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;      case2:        temp = 1+ Math.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;      case3:        temp = 1+ Math.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.put(cur,temp);    returntemp;  }  // method returns maximum survival time  staticintgetMaxSurvivalTime(intA, intB, area X, area Y, area Z)  {    if(A <= 0|| B <= 0)      return0;    HashMap<Pair,Integer> memo = newHashMap<>();    // 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  publicstaticvoidmain(String args[])  {    area X = newarea(3, 2);    area Y = newarea(-5, -10);    area Z = newarea(-20, 5);    intA = 20;    intB = 8;    System.out.println(getMaxSurvivalTime(A, B, X, Y, Z));  }}// This code is contributed by shinjanpatra | 
Python3
| # Python code to get maximum survival time# Class to represent an areaclassarea:    def__init__(self, a, b):        self.a =a        self.b =b# Utility method to get maximum survival timedefmaxSurvival(A, B, X, Y, Z, last, memo):    # if any of A or B is less than 0, return 0    if(A <=0orB <=0):        return0    cur =area(A, B)    # if already calculated, return calculated value    forele inmemo.keys():        if(cur.a ==ele.a andcur.b ==ele.b):            returnmemo[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    returntemp# method returns maximum survival timedefgetMaxSurvivalTime(A, B, X, Y, Z):    if(A <=0orB <=0):        return0    memo =dict()    # At first, we can step into any of the area    returnmax(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 methodX =area(3, 2)Y =area(-5, -10)Z =area(-20, 5)A =20B =8print(getMaxSurvivalTime(A, B, X, Y, Z))# This code is contributed by Soumen Ghosh. | 
C#
| // C# code to get maximum survival timeusingSystem;usingSystem.Collections.Generic;classGFG {  // class to represent an area  classarea {    // increment or decrement in A and B    publicinta, b;    publicarea(inta, intb)    {      this.a = a;      this.b = b;    }  };  // class to represent pair  classPair {    publicintfirst, second;    publicPair(intfirst, intsecond)    {      this.first = first;      this.second = second;    }  }  // Utility method to get maximum of 3 integers  staticintmax(inta, intb, intc)  {    returnMath.Max(a, Math.Max(b, c));  }  // Utility method to get maximum survival time  staticintmaxSurvival(intA, intB, area X, area Y,                         area Z, intlast,                         Dictionary<Pair, int> memo)  {    // if any of A or B is less than 0, return 0    if(A <= 0 || B <= 0)      return0;    Pair cur = newPair(A, B);    // if already calculated, return calculated value    if(memo.ContainsKey(cur))      returnmemo[cur];    inttemp = 0;    // step to areas on basis of last choose area    switch(last) {      case1:        temp          = 1          + Math.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;      case2:        temp          = 1          + Math.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;      case3:        temp          = 1          + Math.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;    returntemp;  }  // method returns maximum survival time  staticintgetMaxSurvivalTime(intA, intB, area X,                                area Y, area Z)  {    if(A <= 0 || B <= 0)      return0;    Dictionary<Pair, int> memo      = newDictionary<Pair, int>();    // At first, we can step into any of the area    returnmax(      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  publicstaticvoidMain(String[] args)  {    area X = newarea(3, 2);    area Y = newarea(-5, -10);    area Z = newarea(-20, 5);    intA = 20;    intB = 8;    Console.WriteLine(      getMaxSurvivalTime(A, B, X, Y, Z));  }}// This code is contributed by lokeshpotta20. | 
Javascript
| <script>// JavaScript code to get maximum survival time// Class to represent an areaclass area{    constructor(a, b){        this.a = a        this.b = b    }}// Utility method to get maximum survival timefunctionmaxSurvival(A, B, X, Y, Z, last, memo){    // if any of A or B is less than 0, return 0    if(A <= 0 || B <= 0)        return0    let cur = newarea(A, B)    // if already calculated, return calculated value    for(let [key,value] of memo){        if(cur.a == key.a && cur.b == key.b)            returnmemo.get(key)    }    let temp;    // step to areas on basis of last chosen area    if(last == 1){        temp = 1 + Math.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))    }    elseif(last == 2){        temp = 1 + Math.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))    }    elseif(last == 3){        temp = 1 + Math.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.set(cur , temp)    returntemp}// method returns maximum survival timefunctiongetMaxSurvivalTime(A, B, X, Y, Z){    if(A <= 0 || B <= 0)        return0    let memo = newMap()    // At first, we can step into any of the area    returnMath.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 methodlet X = newarea(3, 2)let Y = newarea(-5, -10)let Z = newarea(-20, 5)let A = 20let B = 8document.write(getMaxSurvivalTime(A, B, X, Y, Z),"</br>")  // This code is contributed by shinjanpatra</script> | 
5
This article is contributed by Utkarsh Trivedi. If you like zambiatek and would like to contribute, you can also write an article using write.zambiatek.com or mail your article to review-team@zambiatek.com. See your article appearing on the zambiatek 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.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!
 
				 
					

