给定 n 个城市:x1、x2、…… xn:每个城市都与 T[i](宝藏)和 C[i](颜色)相关。您可以选择参观一个城市或跳过它。只允许向前移动。当您访问一个城市时,您会收到以下金额:
- A*T[i] 如果访问城市的颜色与之前访问城市的颜色相同
- B*T[i] 如果这是第一个访问过的城市或者访问过的城市的颜色与之前访问过的城市的颜色不同。T[i]、A 和 B 的值可以为负,而 C[i] ] 范围从 1 到 n。
我们必须计算可能的最大利润。
例子:
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
来源:Oracle 面试经验集 61。
这是标准 0/1 背包问题的变体。这个想法是访问一个城市或跳过它并返回两种情况中的最大值。
下面是上述问题的解决方案。
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[0]);
// 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
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[0]);
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
输出:
133
由于再次评估子问题,因此该问题具有重叠子问题的属性。
以下是基于动态规划的实现。
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[0]);
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
蟒蛇3
# 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
输出:
133
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。