Treasure and Cities

Given n cities: x1, x2, …… xn: each associated with T[i] (treasure) and C[i] (color). You can choose to visit a city or skip it. Only moving in the forward direction is allowed.When you visit a city you receive the following amount:

  1. A*T[i] if the color of visited city is the same as color of previously visited city
  2. B*T[i] if this is the first city visited or if the color of the visited city is different from the color of the previously visited city.The values of T[i], A and B can be negative while C[i] ranges from 1 to n.

We have to compute the maximum profit possible.

Examples:

Input :  A = -5, B = 7
Treasure = {4, 8, 2, 9}
color = {2, 2, 3, 2}
Output : 133
Visit city 2, 3 and 4. Profit = 8*7+2*7+9*7 = 133

Input : A = 5, B = -7 
Treasure = {4, 8, 2, 9}
color = {2, 2, 3, 2}
Output: 57
Visit city 1, 2, 4. Profit = (-7)*4+8*5+9*5 = 57

Source : Oracle Interview Experience Set 61.



This is a variation of standard 0/1 Knapsack problem. The idea is to either visit a city or skip it and return the maximum of both the cases.

Below is the solution of above problem.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

#include <bits/stdc++.h>
using namespace std;
  
// k is current index and col is previous color.
int MaxProfit(int treasure[], int color[], int n,
              int k, int col, int A, int B)
{
    int sum = 0;
  
    if (k == n) // base case
        return 0;
  
    // we have two options
    // either visit current city or skip that
  
    // check if color of this city is equal
    // to prev visited city
    if (col == color[k])
        sum += max(A * treasure[k] + 
                MaxProfit(treasure, color, n, 
                       k + 1, color[k], A, B),
                MaxProfit(treasure, color, n, 
                          k + 1, col, A, B));
    else
        sum += max(B * treasure[k] +                                          
                MaxProfit(treasure, color, n,
                       k + 1, color[k], A, B),
               MaxProfit(treasure, color, n, 
                          k + 1, col, A, B));
  
    // return max of both options
    return sum;
}
  
int main()
{
  
    int A = -5, B = 7;
    int treasure[] = { 4, 8, 2, 9 };
    int color[] = { 2, 2, 6, 2 };
    int n = sizeof(color) / sizeof(color[0]);
  
    // Initially begin with color 0
    cout << MaxProfit(treasure, color, n, 0, 0, A, B);
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# k is current index and col
# is previous color. 
def MaxProfit(treasure, color, n, 
                    k, col, A, B):
    sum = 0
    if k == n:
        return 0
  
    # we have two options either
    # visit current city or skip that 
  
    # check if color of this city 
    # is equal to prev visited city 
    if col== color[k]:
        sum += max(A * treasure[k] +
                MaxProfit(treasure, color, n, 
                       k + 1, color[k], A, B), 
                MaxProfit(treasure, color, n, 
                            k + 1, col, A, B))
    else:
        sum += max(B * treasure[k] +                                        
               MaxProfit(treasure, color, n, 
                        k + 1, color[k], A, B), 
               MaxProfit(treasure, color, n, 
                           k + 1, col, A, B))
  
    # return max of both options
    return sum
  
# Driver Code
A = -5
B= 7
treasure = [4, 8, 2, 9]
color = [2, 2, 6, 2]
n = len(color)
  
# Initially begin with color 0
print( MaxProfit(treasure, color,
                 n, 0, 0, A, B))
  
# This code is contributed 
# by Shrikant13

chevron_right