# Treasure and Cities

• Difficulty Level : Hard
• Last Updated : 23 Jul, 2021

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.

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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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++

 `#include ``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);` `    ``// Initially begin with color 0``    ``cout << MaxProfit(treasure, color, n, 0, 0, A, B);``    ``return` `0;``}`

## Java

 `class` `GFG{` `// k is current index and col is previous color.``static` `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 += Math.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 += Math.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;``}` `public` `static` `void` `main(String[] args)``{` `    ``int` `A = -``5``, B = ``7``;``    ``int` `treasure[] = { ``4``, ``8``, ``2``, ``9` `};``    ``int` `color[] = { ``2``, ``2``, ``6``, ``2` `};``    ``int` `n = color.length;` `    ``// Initially begin with color 0``    ``System.out.print(MaxProfit(treasure, color, n, ``0``, ``0``, A, B));``}``}` `// This code is contributed by PrinciRaj1992`

## Python3

 `# 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`

## C#

 `using` `System;` `class` `GFG``{` `// k is current index and col is previous color.``static` `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 += Math.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 += Math.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``public` `static` `void` `Main(String[] args)``{` `    ``int` `A = -5, B = 7;``    ``int` `[]treasure = { 4, 8, 2, 9 };``    ``int` `[]color = { 2, 2, 6, 2 };``    ``int` `n = color.Length;` `    ``// Initially begin with color 0``    ``Console.Write(MaxProfit(treasure, color, n, 0, 0, A, B));``}``}` `// This code is contributed by PrinciRaj1992`

## Javascript

 ``
Output:
`133`

Since subproblems are evaluated again, this problem has Overlapping Subproblems property.

Following is Dynamic Programming based implementation.

## C++

 `// A memoization based program to find maximum``// treasure that can be collected.``#include ``using` `namespace` `std;` `const` `int` `MAX = 1001;` `int` `dp[MAX][MAX];` `// 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)``{``    ``if` `(k == n) ``// base case``        ``return` `dp[k][col] = 0;` `    ``if` `(dp[k][col] != -1)``        ``return` `dp[k][col];` `    ``int` `sum = 0;` `    ``// we have two options``    ``// either visit current city or skip that` `    ``if` `(col == color[k]) ``// check if color of this city is equal to prev visited city``        ``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` `dp[k][col] = 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);``    ``memset``(dp, -1, ``sizeof``(dp));``    ``cout << MaxProfit(treasure, color, n, 0, 0, A, B);``    ``return` `0;``}`

## Java

 `// A memoization based program to find maximum``// treasure that can be collected.``import` `java.util.*;` `class` `GFG``{` `static` `int` `MAX = ``1001``;` `static` `int` `[][]dp = ``new` `int``[MAX][MAX];` `// k is current index and col is previous color.``static` `int` `MaxProfit(``int` `treasure[], ``int` `color[], ``int` `n,``            ``int` `k, ``int` `col, ``int` `A, ``int` `B)``{``    ``if` `(k == n) ``// base case``        ``return` `dp[k][col] = ``0``;` `    ``if` `(dp[k][col] != -``1``)``        ``return` `dp[k][col];` `    ``int` `sum = ``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 += Math.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 += Math.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` `dp[k][col] = sum;``}` `// Driver code``public` `static` `void` `main(String[] args)``{``    ``int` `A = -``5``, B = ``7``;``    ``int` `treasure[] = { ``4``, ``8``, ``2``, ``9` `};``    ``int` `color[] = { ``2``, ``2``, ``6``, ``2` `};``    ``int` `n = color.length;``    ``for` `(``int` `i = ``0``; i < n; i++)``        ``for` `(``int` `j = ``0``; j < MAX; j++)``            ``dp[i][j] = -``1``;``    ``System.out.print(MaxProfit(treasure, color, n, ``0``, ``0``, A, B));``}``}` `// This code is contributed by 29AjayKumar`

## Python3

 `# A memoization based program to find maximum``# treasure that can be collected.``MAX` `=` `1001` `dp ``=` `[[``-``1` `for` `i ``in` `range``(``MAX``)] ``for` `i ``in` `range``(``MAX``)]` `# k is current index and col is previous color.``def` `MaxProfit(treasure, color, n,k, col, A, B):``    ``if` `(k ``=``=` `n):``        ` `        ``# base case``        ``dp[k][col] ``=` `0``        ``return` `dp[k][col]``    ``if` `(dp[k][col] !``=` `-``1``):``        ``return` `dp[k][col]``    ` `    ``summ ``=` `0``    ` `    ``# we have two options``    ``# either visit current city or skip that``    ``if` `(col ``=``=` `color[k]):``        ` `        ``# check if color of this city is equal to prev visited city``        ``summ ``+``=` `max``(A ``*` `treasure[k] ``+` `MaxProfit(treasure,``                ``color, n, k ``+` `1``,color[k], A, B),``                ``MaxProfit(treasure, color, n, k ``+` `1``, col, A, B))``    ``else``:``        ``summ ``+``=` `max``(B ``*` `treasure[k] ``+` `MaxProfit(treasure,``                ``color, n, k ``+` `1``,color[k], A, B),``                ``MaxProfit(treasure, color, n, k ``+` `1``, col, A, B))``    ``dp[k][col] ``=` `summ``    ` `    ``# return max of both options``    ``return` `dp[k][col]` `# Driver code``A ``=` `-``5``B ``=` `7``treasure ``=` `[ ``4``, ``8``, ``2``, ``9` `]``color ``=` `[ ``2``, ``2``, ``6``, ``2` `]``n ``=` `len``(color)``print``(MaxProfit(treasure, color, n, ``0``, ``0``, A, B))` `# This code is contributed by shubhamsingh10`

## C#

 `// A memoization based program to find maximum``// treasure that can be collected.``using` `System;` `class` `GFG``{`` ` `static` `int` `MAX = 1001;`` ` `static` `int` `[,]dp = ``new` `int``[MAX, MAX];`` ` `// k is current index and col is previous color.``static` `int` `MaxProfit(``int` `[]treasure, ``int` `[]color, ``int` `n,``            ``int` `k, ``int` `col, ``int` `A, ``int` `B)``{``    ``if` `(k == n) ``// base case``        ``return` `dp[k, col] = 0;`` ` `    ``if` `(dp[k, col] != -1)``        ``return` `dp[k, col];`` ` `    ``int` `sum = 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 += Math.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 += Math.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` `dp[k, col] = sum;``}`` ` `// Driver code``public` `static` `void` `Main(String[] args)``{``    ``int` `A = -5, B = 7;``    ``int` `[]treasure = { 4, 8, 2, 9 };``    ``int` `[]color = { 2, 2, 6, 2 };``    ``int` `n = color.Length;``    ``for` `(``int` `i = 0; i < n; i++)``        ``for` `(``int` `j = 0; j < MAX; j++)``            ``dp[i, j] = -1;``    ``Console.Write(MaxProfit(treasure, color, n, 0, 0, A, B));``}``}` `// This code is contributed by PrinciRaj1992`

## Javascript

 ``
Output:
`133`

My Personal Notes arrow_drop_up