给定两个整数N和M ,其中N是放置在一行中的盒子的数量, M是分布在这些盒子中的钻石颜色的数量,这样每个盒子中至少包含1 个钻石。每个钻石都有一个颜色和一个由M * N矩阵表示的值,其中mat[i][j]表示第j个框中颜色为i的钻石的数量。任务是从每个盒子中取出一种颜色类型的钻石,使得所选钻石的总价值最大,而从相邻盒子中取出的钻石颜色不同。如果不可能满足条件,则打印-1 。
例子:
Input: mat[][] = {
{10, 2, 20, 0},
{0, 0, 5, 0},
{0, 0, 0, 6},
{4, 0, 11, 5},
{0, 0, 0, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}}
Output: 23
Explanation: From box 1, we can choose either 10 diamonds of Colour1 or 4 diamonds of Colour4. But since from box 2, we have to choose 2 diamonds of Colour1, therefore choose 4 diamonds of Colour4 from box 1.
Similarly, to maximize the diamonds count, choose 11 diamonds of Colour4 from box 3 and 6 diamonds of Colour3 from box 4.
The total diamonds chosen = 4 + 2 + 11 + 6 = 23, which is the maximum count possible.
Input: mat[][] = {
{1, 0, 0},
{0, 0, 5},
{0, 11, 5},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}}
Output: 16
Explanation: We choose 1 from the 1st box of Colour1, 11 from the 2nd box of Colour3, and 5 from the 3rd box of Colour2.
方法:
- 动态规划可以用来解决这个问题。
- 制作一个大小为M x N的二维数组,定义将通过选择第j列的第i个颜色是可以获得的最大值。
- 递推关系将是dp[i][j] = arr[i][j] + max of (dp[1…M][i-1]) 。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the maximized value
int maxSum(vector > arr)
{
// Number of rows and columns
int m = (int)arr.size();
int n = (int)arr[0].size() - 1;
// Creating the Dp array
int dp[m][n + 1];
// memset(arr, 0, sizeof(arr));
memset(dp, 0, sizeof(dp));
// Populating the first column
for (int i = 1; i < m; ++i)
dp[i][1] = arr[i][1];
for (int i = 1; i < n + 1; ++i) {
// Iterating over all the rows
for (int j = 1; j < m; ++j) {
int mx = 0;
// Getting the (i-1)th max value
for (int k = 1; k < m; ++k) {
if (k != j) {
if (dp[k][i - 1] > mx) {
mx = dp[k][i - 1];
}
}
}
// Adding it to the current cell
if (mx and arr[j][i]) {
dp[j][i] = arr[j][i] + mx;
}
}
}
// Getting the max sum
// from the last column
int ans = -1;
for (int i = 1; i <= m; ++i) {
if (dp[i][n])
ans = max(ans, dp[i][n]);
}
return ans;
}
// Driver code
int main()
{
// Columns are indexed 1-based
vector > arr = {
{ 0, 0, 0, 0, 0 },
{ 0, 10, 2, 20, 0 },
{ 0, 0, 0, 5, 0 },
{ 0, 0, 0, 0, 6 },
{ 0, 4, 0, 11, 5 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 }
};
cout << maxSum(arr);
return 0;
}
Java
// Java implementation of the approach
import java.io.*;
import java.util.*;
class GFG{
// Function to return the maximized value
static int maxSum(int[][] arr)
{
// Number of rows and columns
int m = (int)arr.length;
int n = (int)arr[0].length - 1;
// Creating the Dp array
int[][] dp = new int[m + 1][n + 2];
// memset(arr, 0, sizeof(arr));
for(int i = 0; i <= m; i++)
{
for(int j = 0; j <= n + 1; j++)
{
dp[i][j] = 0;
}
}
// Populating the first column
for(int i = 1; i < m; ++i)
dp[i][1] = arr[i][1];
for(int i = 1; i < n + 1; ++i)
{
// Iterating over all the rows
for(int j = 1; j < m; ++j)
{
int mx = 0;
// Getting the (i-1)th max value
for(int k = 1; k < m; ++k)
{
if (k != j)
{
if (dp[k][i - 1] > mx)
{
mx = dp[k][i - 1];
}
}
}
// Adding it to the current cell
if (mx != 0 && arr[j][i] != 0)
{
dp[j][i] = arr[j][i] + mx;
}
}
}
// Getting the max sum
// from the last column
int ans = -1;
for(int i = 1; i <= m; ++i)
{
if ((dp[i][n]) != 0)
ans = Math.max(ans, dp[i][n]);
}
return ans;
}
// Driver code
public static void main(String[] args)
{
// Columns are indexed 1-based
int[][] arr = { { 0, 0, 0, 0, 0 },
{ 0, 10, 2, 20, 0 },
{ 0, 0, 0, 5, 0 },
{ 0, 0, 0, 0, 6 },
{ 0, 4, 0, 11, 5 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 } };
System.out.println(maxSum(arr));
}
}
// This code is contributed by sanjoy_62
Python3
# Python 3 implementation of the approach
# Function to return the maximized value
def maxSum(arr):
# Number of rows and columns
m = len(arr)
n = len(arr[0]) - 1
# Creating the Dp array
dp = [[0 for i in range(n+1)] for j in range(m)]
# Populating the first column
for i in range(1,m,1):
dp[i][1] = arr[i][1]
for i in range(1,n + 1,1):
# Iterating over all the rows
for j in range(1,m,1):
mx = 0
# Getting the (i-1)th max value
for k in range(1,m,1):
if (k != j):
if (dp[k][i - 1] > mx):
mx = dp[k][i - 1]
# Adding it to the current cell
if (mx and arr[j][i]):
dp[j][i] = arr[j][i] + mx
# Getting the max sum
# from the last column
ans = -1
for i in range(1,m,1):
if (dp[i][n]):
ans = max(ans, dp[i][n])
return ans
# Driver code
if __name__ == '__main__':
# Columns are indexed 1-based
arr = [[0, 0, 0, 0, 0],
[0, 10, 2, 20, 0],
[0, 0, 0, 5, 0],
[0, 0, 0, 0, 6],
[0, 4, 0, 11, 5],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]]
print(maxSum(arr))
# This coe is contributed by bgangwar59.
C#
// C# implementation of the approach
using System;
public class GFG
{
// Function to return the maximized value
static int maxSum(int[,] arr)
{
// Number of rows and columns
int m = (int)arr.GetLength(0);
int n = (int)arr.GetLength(1) - 1;
// Creating the Dp array
int[,] dp = new int[m + 1,n + 2];
// memset(arr, 0, sizeof(arr));
for(int i = 0; i <= m; i++)
{
for(int j = 0; j <= n + 1; j++)
{
dp[i,j] = 0;
}
}
// Populating the first column
for(int i = 1; i < m; ++i)
dp[i,1] = arr[i,1];
for(int i = 1; i < n + 1; ++i)
{
// Iterating over all the rows
for(int j = 1; j < m; ++j)
{
int mx = 0;
// Getting the (i-1)th max value
for(int k = 1; k < m; ++k)
{
if (k != j)
{
if (dp[k,i - 1] > mx)
{
mx = dp[k,i - 1];
}
}
}
// Adding it to the current cell
if (mx != 0 && arr[j,i] != 0)
{
dp[j,i] = arr[j,i] + mx;
}
}
}
// Getting the max sum
// from the last column
int ans = -1;
for(int i = 1; i <= m; ++i)
{
if ((dp[i,n]) != 0)
ans = Math.Max(ans, dp[i,n]);
}
return ans;
}
// Driver code
public static void Main(String[] args)
{
// Columns are indexed 1-based
int[,] arr = { { 0, 0, 0, 0, 0 },
{ 0, 10, 2, 20, 0 },
{ 0, 0, 0, 5, 0 },
{ 0, 0, 0, 0, 6 },
{ 0, 4, 0, 11, 5 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0 } };
Console.WriteLine(maxSum(arr));
}
}
// This code is contributed by shikhasingrajput
Javascript
23
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。