给定一个N行M列的矩阵。假定M是3的倍数。列分为3个部分,第一个部分是从0到m / 3-1,第二个部分是从m / 3到2m / 3-1,第三个部分从2m / 3到m。任务是从每一行中选择一个元素,而在相邻行中,我们不能从同一部分中选择。我们必须最大化所选元素的总和。
例子:
Input: mat[][] = {
{1, 3, 5, 2, 4, 6},
{6, 4, 5, 1, 3, 2},
{1, 3, 5, 2, 4, 6},
{6, 4, 5, 1, 3, 2},
{6, 4, 5, 1, 3, 2},
{1, 3, 5, 2, 4, 6}}
Output: 35
Input: mat[][] = {
{1, 2, 3},
{3, 2, 1},
{5, 4, 2}
Output: 10
方法:可以通过存储子问题并重用它们来使用动态编程解决方案来解决该问题。创建一个dp [] []数组,其中dp [i] [0]代表从0到i的行的元素总和,采用第1节的元素。类似地,对于dp [i] [1]和dp [i] [2] 。因此,打印max(dp [n – 1] [0],dp [n – 1] [1],dp [n – 1] [2] 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
const int n = 6, m = 6;
// Function to find the maximum value
void maxSum(long arr[n][m])
{
// Dp table
long dp[n + 1][3] = { 0 };
// Fill the dp in bottom
// up manner
for (int i = 0; i < n; i++) {
// Maximum of the three sections
long m1 = 0, m2 = 0, m3 = 0;
for (int j = 0; j < m; j++) {
// Maximum of the first section
if ((j / (m / 3)) == 0) {
m1 = max(m1, arr[i][j]);
}
// Maximum of the second section
else if ((j / (m / 3)) == 1) {
m2 = max(m2, arr[i][j]);
}
// Maximum of the third section
else if ((j / (m / 3)) == 2) {
m3 = max(m3, arr[i][j]);
}
}
// If we choose element from section 1,
// we cannot have selection from same section
// in adjacent rows
dp[i + 1][0] = max(dp[i][1], dp[i][2]) + m1;
dp[i + 1][1] = max(dp[i][0], dp[i][2]) + m2;
dp[i + 1][2] = max(dp[i][1], dp[i][0]) + m3;
}
// Print the maximum sum
cout << max(max(dp[n][0], dp[n][1]), dp[n][2]) << '\n';
}
// Driver code
int main()
{
long arr[n][m] = { { 1, 3, 5, 2, 4, 6 },
{ 6, 4, 5, 1, 3, 2 },
{ 1, 3, 5, 2, 4, 6 },
{ 6, 4, 5, 1, 3, 2 },
{ 6, 4, 5, 1, 3, 2 },
{ 1, 3, 5, 2, 4, 6 } };
maxSum(arr);
return 0;
}
Java
// Java program for the above approach
class GFG
{
static int n = 6, m = 6;
// Function to find the maximum value
static void maxSum(long arr[][])
{
// Dp table
long [][]dp= new long[n + 1][3];
// Fill the dp in bottom
// up manner
for (int i = 0; i < n; i++)
{
// Maximum of the three sections
long m1 = 0, m2 = 0, m3 = 0;
for (int j = 0; j < m; j++)
{
// Maximum of the first section
if ((j / (m / 3)) == 0)
{
m1 = Math.max(m1, arr[i][j]);
}
// Maximum of the second section
else if ((j / (m / 3)) == 1)
{
m2 = Math.max(m2, arr[i][j]);
}
// Maximum of the third section
else if ((j / (m / 3)) == 2)
{
m3 = Math.max(m3, arr[i][j]);
}
}
// If we choose element from section 1,
// we cannot have selection from same section
// in adjacent rows
dp[i + 1][0] = Math.max(dp[i][1], dp[i][2]) + m1;
dp[i + 1][1] = Math.max(dp[i][0], dp[i][2]) + m2;
dp[i + 1][2] = Math.max(dp[i][1], dp[i][0]) + m3;
}
// Print the maximum sum
System.out.print(Math.max(Math.max(dp[n][0], dp[n][1]), dp[n][2]) + "\n");
}
// Driver code
public static void main(String[] args)
{
long arr[][] = { { 1, 3, 5, 2, 4, 6 },
{ 6, 4, 5, 1, 3, 2 },
{ 1, 3, 5, 2, 4, 6 },
{ 6, 4, 5, 1, 3, 2 },
{ 6, 4, 5, 1, 3, 2 },
{ 1, 3, 5, 2, 4, 6 } };
maxSum(arr);
}
}
// This code is contributed by PrinciRaj1992
Python3
# Python3 program for the above approach
import numpy as np
n = 6; m = 6;
# Function to find the maximum value
def maxSum(arr) :
# Dp table
dp = np.zeros((n + 1, 3));
# Fill the dp in bottom
# up manner
for i in range(n) :
# Maximum of the three sections
m1 = 0; m2 = 0; m3 = 0;
for j in range(m) :
# Maximum of the first section
if ((j // (m // 3)) == 0) :
m1 = max(m1, arr[i][j]);
# Maximum of the second section
elif ((j // (m // 3)) == 1) :
m2 = max(m2, arr[i][j]);
# Maximum of the third section
elif ((j // (m // 3)) == 2) :
m3 = max(m3, arr[i][j]);
# If we choose element from section 1,
# we cannot have selection from same section
# in adjacent rows
dp[i + 1][0] = max(dp[i][1], dp[i][2]) + m1;
dp[i + 1][1] = max(dp[i][0], dp[i][2]) + m2;
dp[i + 1][2] = max(dp[i][1], dp[i][0]) + m3;
# Print the maximum sum
print(max(max(dp[n][0], dp[n][1]), dp[n][2]));
# Driver code
if __name__ == "__main__" :
arr = [[ 1, 3, 5, 2, 4, 6 ],
[ 6, 4, 5, 1, 3, 2 ],
[ 1, 3, 5, 2, 4, 6 ],
[ 6, 4, 5, 1, 3, 2 ],
[ 6, 4, 5, 1, 3, 2 ],
[ 1, 3, 5, 2, 4, 6 ]];
maxSum(arr);
# This code is contributed by AnkitRai01
C#
// C# program for the above approach
using System;
class GFG
{
static int n = 6, m = 6;
// Function to find the maximum value
static void maxSum(long [,]arr)
{
// Dp table
long [,]dp = new long[n + 1, 3];
// Fill the dp in bottom
// up manner
for (int i = 0; i < n; i++)
{
// Maximum of the three sections
long m1 = 0, m2 = 0, m3 = 0;
for (int j = 0; j < m; j++)
{
// Maximum of the first section
if ((j / (m / 3)) == 0)
{
m1 = Math.Max(m1, arr[i, j]);
}
// Maximum of the second section
else if ((j / (m / 3)) == 1)
{
m2 = Math.Max(m2, arr[i, j]);
}
// Maximum of the third section
else if ((j / (m / 3)) == 2)
{
m3 = Math.Max(m3, arr[i, j]);
}
}
// If we choose element from section 1,
// we cannot have selection from same section
// in adjacent rows
dp[i + 1, 0] = Math.Max(dp[i, 1], dp[i, 2]) + m1;
dp[i + 1, 1] = Math.Max(dp[i, 0], dp[i, 2]) + m2;
dp[i + 1, 2] = Math.Max(dp[i, 1], dp[i, 0]) + m3;
}
// Print the maximum sum
Console.Write(Math.Max(Math.Max(dp[n, 0],
dp[n, 1]),
dp[n, 2]) + "\n");
}
// Driver code
public static void Main(String[] args)
{
long [,]arr = { { 1, 3, 5, 2, 4, 6 },
{ 6, 4, 5, 1, 3, 2 },
{ 1, 3, 5, 2, 4, 6 },
{ 6, 4, 5, 1, 3, 2 },
{ 6, 4, 5, 1, 3, 2 },
{ 1, 3, 5, 2, 4, 6 } };
maxSum(arr);
}
}
// This code is contributed by 29AjayKumar
输出:
35
时间复杂度: O(N * M)