 Open in App
Not now

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

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