给定大小为nxn的矩阵,找到总和最大的之字形序列的总和。之字形序列从顶部开始,在底部结束。序列的两个连续元素不能属于同一列。
例子:
Input : mat[][] = 3 1 2
4 8 5
6 9 7
Output : 18
Zigzag sequence is: 3->8->7
Another such sequence is 2->4->7
Input : mat[][] = 4 2 1
3 9 6
11 3 15
Output : 28
这个问题具有最优子结构。
Maximum Zigzag sum starting from arr[i][j] to a
bottom cell can be written as :
zzs(i, j) = arr[i][j] + max(zzs(i+1, k)),
where k = 0, 1, 2 and k != j
zzs(i, j) = arr[i][j], if i = n-1
We have to find the largest among all as
Result = zzs(0, j) where 0 <= j < n
C++
// C++ program to find the largest sum zigzag sequence
#include
using namespace std;
const int MAX = 100;
// Returns largest sum of a Zigzag sequence starting
// from (i, j) and ending at a bottom cell.
int largestZigZagSumRec(int mat[][MAX], int i,
int j, int n)
{
// If we have reached bottom
if (i == n-1)
return mat[i][j];
// Find the largest sum by considering all
// possible next elements in sequence.
int zzs = 0;
for (int k=0; k
Java
// Java program to find the largest sum
// zigzag sequence
import java.io.*;
class GFG {
static int MAX = 100;
// Returns largest sum of a Zigzag
// sequence starting from (i, j)
// and ending at a bottom cell.
static int largestZigZagSumRec(int mat[][],
int i, int j, int n)
{
// If we have reached bottom
if (i == n-1)
return mat[i][j];
// Find the largest sum by considering all
// possible next elements in sequence.
int zzs = 0;
for (int k=0; k
Python 3
# Python3 program to find the largest
# sum zigzag sequence
MAX = 100
# Returns largest sum of a Zigzag
# sequence starting from (i, j) and
# ending at a bottom cell.
def largestZigZagSumRec( mat, i, j, n):
# If we have reached bottom
if (i == n-1):
return mat[i][j]
# Find the largest sum by considering all
# possible next elements in sequence.
zzs = 0
for k in range(n):
if (k != j):
zzs = max(zzs, largestZigZagSumRec(mat, i + 1, k, n))
return zzs + mat[i][j]
# Returns largest possible sum of a
# Zizag sequence starting from top
# and ending at bottom.
def largestZigZag(mat, n):
# Consider all cells of top row as
# starting point
res = 0
for j in range(n):
res = max(res, largestZigZagSumRec(mat, 0, j, n))
return res
# Driver Code
if __name__ == "__main__":
n = 3
mat = [ [4, 2, 1],
[3, 9, 6],
[11, 3, 15]]
print("Largest zigzag sum: " ,
largestZigZag(mat, n))
# This code is contributed by ChitraNayal
C#
// C# program to find the largest sum
// zigzag sequence
using System;
class GFG {
// static int MAX = 100;
// Returns largest sum of a Zigzag
// sequence starting from (i, j)
// and ending at a bottom cell.
static int largestZigZagSumRec(int [,]mat,
int i, int j, int n)
{
// If we have reached bottom
if (i == n-1)
return mat[i,j];
// Find the largest sum by considering all
// possible next elements in sequence.
int zzs = 0;
for (int k = 0; k < n; k++)
if (k != j)
zzs = Math.Max(zzs, largestZigZagSumRec(mat,
i + 1, k, n));
return zzs + mat[i,j];
}
// Returns largest possible
// sum of a Zizag sequence
// starting from top and ending
// at bottom.
static int largestZigZag(int [,]mat, int n)
{
// Consider all cells of
// top row as starting
// point
int res = 0;
for (int j = 0; j < n; j++)
res = Math.Max(res,
largestZigZagSumRec(mat, 0, j, n));
return res;
}
// Driver Code
public static void Main ()
{
int n = 3;
int [,]mat = {{4, 2, 1},
{3, 9, 6},
{11, 3, 15}};
Console.WriteLine("Largest zigzag sum: "
+ largestZigZag(mat, n));
}
}
// This code is contributed by anuj_67.
PHP
C++
// Memoization based C++ program to find the largest
// sum zigzag sequence
#include
using namespace std;
const int MAX = 100;
int dp[MAX][MAX];
// Returns largest sum of a Zigzag sequence starting
// from (i, j) and ending at a bottom cell.
int largestZigZagSumRec(int mat[][MAX], int i,
int j, int n)
{
if (dp[i][j] != -1)
return dp[i][j];
// If we have reached bottom
if (i == n-1)
return (dp[i][j] = mat[i][j]);
// Find the largest sum by considering all
// possible next elements in sequence.
int zzs = 0;
for (int k=0; k
Java
// Memoization based Java program to find the largest
// sum zigzag sequence
class GFG
{
static int MAX = 100;
static int [][]dp = new int[MAX][MAX];
// Returns largest sum of a Zigzag sequence starting
// from (i, j) and ending at a bottom cell.
static int largestZigZagSumRec(int mat[][], int i,
int j, int n)
{
if (dp[i][j] != -1)
return dp[i][j];
// If we have reached bottom
if (i == n - 1)
return (dp[i][j] = mat[i][j]);
// Find the largest sum by considering all
// possible next elements in sequence.
int zzs = 0;
for (int k = 0; k < n; k++)
if (k != j)
zzs = Math.max(zzs, largestZigZagSumRec(mat,
i + 1, k, n));
return (dp[i][j] = (zzs + mat[i][j]));
}
// Returns largest possible sum of a Zizag sequence
// starting from top and ending at bottom.
static int largestZigZag(int mat[][], int n)
{
for (int i = 0; i < MAX; i++)
for (int k = 0; k < MAX; k++)
dp[i][k] = -1;
// Consider all cells of top row as starting point
int res = 0;
for (int j = 0; j < n; j++)
res = Math.max(res, largestZigZagSumRec(mat,
0, j, n));
return res;
}
// Driver code
public static void main(String[] args)
{
int n = 3;
int mat[][] = { {4, 2, 1},
{3, 9, 6},
{11, 3, 15}};
System.out.print("Largest zigzag sum: " +
largestZigZag(mat, n));
}
}
// This code is contributed by PrinciRaj1992
Python3
# Memoization based Python3 program to find the largest
# sum zigzag sequence
MAX = 100;
dp = [[0 for i in range(MAX)] for j in range(MAX)]
# Returns largest sum of a Zigzag sequence starting
# from (i, j) and ending at a bottom cell.
def largestZigZagSumRec(mat, i, j, n):
if (dp[i][j] != -1):
return dp[i][j];
# If we have reached bottom
if (i == n - 1):
dp[i][j] = mat[i][j];
return (dp[i][j]);
# Find the largest sum by considering all
# possible next elements in sequence.
zzs = 0;
for k in range(n):
if (k != j):
zzs = max(zzs, largestZigZagSumRec(mat,
i + 1, k, n));
dp[i][j] = (zzs + mat[i][j]);
return (dp[i][j]);
# Returns largest possible sum of a Zizag sequence
# starting from top and ending at bottom.
def largestZigZag(mat, n):
for i in range(MAX):
for k in range(MAX):
dp[i][k] = -1;
# Consider all cells of top row as starting point
res = 0;
for j in range(n):
res = max(res, largestZigZagSumRec(mat, 0, j, n));
return res;
# Driver code
if __name__ == '__main__':
n = 3;
mat = [[4, 2, 1], [3, 9, 6], [11, 3, 15]];
print("Largest zigzag sum: ", largestZigZag(mat, n));
# This code is contributed by Rajput-Ji
C#
// Memoization based C# program to find the largest
// sum zigzag sequence
using System;
class GFG
{
static int MAX = 100;
static int [,]dp = new int[MAX, MAX];
// Returns largest sum of a Zigzag sequence starting
// from (i, j) and ending at a bottom cell.
static int largestZigZagSumRec(int [,]mat, int i,
int j, int n)
{
if (dp[i, j] != -1)
return dp[i, j];
// If we have reached bottom
if (i == n - 1)
return (dp[i, j] = mat[i, j]);
// Find the largest sum by considering all
// possible next elements in sequence.
int zzs = 0;
for (int k = 0; k < n; k++)
if (k != j)
zzs = Math.Max(zzs, largestZigZagSumRec(mat,
i + 1, k, n));
return (dp[i, j] = (zzs + mat[i, j]));
}
// Returns largest possible sum of a Zizag sequence
// starting from top and ending at bottom.
static int largestZigZag(int [,]mat, int n)
{
for (int i = 0; i < MAX; i++)
for (int k = 0; k < MAX; k++)
dp[i, k] = -1;
// Consider all cells of top row as starting point
int res = 0;
for (int j = 0; j < n; j++)
res = Math.Max(res, largestZigZagSumRec(mat,
0, j, n));
return res;
}
// Driver code
public static void Main(String[] args)
{
int n = 3;
int [,]mat = { {4, 2, 1},
{3, 9, 6},
{11, 3, 15}};
Console.Write("Largest zigzag sum: " +
largestZigZag(mat, n));
}
}
// This code is contributed by 29AjayKumar
输出:
Largest zigzag sum: 28
重叠子问题
考虑到以上实现,对于大小为3 x 3的矩阵mat [] [],以找到元素mat(i,j)的之字形和(zzs),形成以下递归树。
Recursion tree for cell (0, 0)
zzs(0,0)
/ \
zzs(1,1) zzs(1,2)
/ \ / \
zzs(2,0) zzs(2,2) zzs(2,0) zzs(2,1)
Recursion tree for cell (0, 1)
zzs(0,1)
/ \
zzs(1,0) zzs(1,2)
/ \ / \
zzs(2,1) zzs(2,2) zzs(2,0) zzs(2,1)
Recursion tree for cell (0, 2)
zzs(0,2)
/ \
zzs(1,0) zzs(1,1)
/ \ / \
zzs(2,1) zzs(2,2) zzs(2,0) zzs(2,2)
我们可以看到,有许多子问题一次又一次地得到解决。因此,此问题具有“重叠子结构”属性,可以通过使用“记忆化”或“制表”来避免相同子问题的重新计算。以下是LIS问题的列表化实施。
C++
// Memoization based C++ program to find the largest
// sum zigzag sequence
#include
using namespace std;
const int MAX = 100;
int dp[MAX][MAX];
// Returns largest sum of a Zigzag sequence starting
// from (i, j) and ending at a bottom cell.
int largestZigZagSumRec(int mat[][MAX], int i,
int j, int n)
{
if (dp[i][j] != -1)
return dp[i][j];
// If we have reached bottom
if (i == n-1)
return (dp[i][j] = mat[i][j]);
// Find the largest sum by considering all
// possible next elements in sequence.
int zzs = 0;
for (int k=0; k
Java
// Memoization based Java program to find the largest
// sum zigzag sequence
class GFG
{
static int MAX = 100;
static int [][]dp = new int[MAX][MAX];
// Returns largest sum of a Zigzag sequence starting
// from (i, j) and ending at a bottom cell.
static int largestZigZagSumRec(int mat[][], int i,
int j, int n)
{
if (dp[i][j] != -1)
return dp[i][j];
// If we have reached bottom
if (i == n - 1)
return (dp[i][j] = mat[i][j]);
// Find the largest sum by considering all
// possible next elements in sequence.
int zzs = 0;
for (int k = 0; k < n; k++)
if (k != j)
zzs = Math.max(zzs, largestZigZagSumRec(mat,
i + 1, k, n));
return (dp[i][j] = (zzs + mat[i][j]));
}
// Returns largest possible sum of a Zizag sequence
// starting from top and ending at bottom.
static int largestZigZag(int mat[][], int n)
{
for (int i = 0; i < MAX; i++)
for (int k = 0; k < MAX; k++)
dp[i][k] = -1;
// Consider all cells of top row as starting point
int res = 0;
for (int j = 0; j < n; j++)
res = Math.max(res, largestZigZagSumRec(mat,
0, j, n));
return res;
}
// Driver code
public static void main(String[] args)
{
int n = 3;
int mat[][] = { {4, 2, 1},
{3, 9, 6},
{11, 3, 15}};
System.out.print("Largest zigzag sum: " +
largestZigZag(mat, n));
}
}
// This code is contributed by PrinciRaj1992
Python3
# Memoization based Python3 program to find the largest
# sum zigzag sequence
MAX = 100;
dp = [[0 for i in range(MAX)] for j in range(MAX)]
# Returns largest sum of a Zigzag sequence starting
# from (i, j) and ending at a bottom cell.
def largestZigZagSumRec(mat, i, j, n):
if (dp[i][j] != -1):
return dp[i][j];
# If we have reached bottom
if (i == n - 1):
dp[i][j] = mat[i][j];
return (dp[i][j]);
# Find the largest sum by considering all
# possible next elements in sequence.
zzs = 0;
for k in range(n):
if (k != j):
zzs = max(zzs, largestZigZagSumRec(mat,
i + 1, k, n));
dp[i][j] = (zzs + mat[i][j]);
return (dp[i][j]);
# Returns largest possible sum of a Zizag sequence
# starting from top and ending at bottom.
def largestZigZag(mat, n):
for i in range(MAX):
for k in range(MAX):
dp[i][k] = -1;
# Consider all cells of top row as starting point
res = 0;
for j in range(n):
res = max(res, largestZigZagSumRec(mat, 0, j, n));
return res;
# Driver code
if __name__ == '__main__':
n = 3;
mat = [[4, 2, 1], [3, 9, 6], [11, 3, 15]];
print("Largest zigzag sum: ", largestZigZag(mat, n));
# This code is contributed by Rajput-Ji
C#
// Memoization based C# program to find the largest
// sum zigzag sequence
using System;
class GFG
{
static int MAX = 100;
static int [,]dp = new int[MAX, MAX];
// Returns largest sum of a Zigzag sequence starting
// from (i, j) and ending at a bottom cell.
static int largestZigZagSumRec(int [,]mat, int i,
int j, int n)
{
if (dp[i, j] != -1)
return dp[i, j];
// If we have reached bottom
if (i == n - 1)
return (dp[i, j] = mat[i, j]);
// Find the largest sum by considering all
// possible next elements in sequence.
int zzs = 0;
for (int k = 0; k < n; k++)
if (k != j)
zzs = Math.Max(zzs, largestZigZagSumRec(mat,
i + 1, k, n));
return (dp[i, j] = (zzs + mat[i, j]));
}
// Returns largest possible sum of a Zizag sequence
// starting from top and ending at bottom.
static int largestZigZag(int [,]mat, int n)
{
for (int i = 0; i < MAX; i++)
for (int k = 0; k < MAX; k++)
dp[i, k] = -1;
// Consider all cells of top row as starting point
int res = 0;
for (int j = 0; j < n; j++)
res = Math.Max(res, largestZigZagSumRec(mat,
0, j, n));
return res;
}
// Driver code
public static void Main(String[] args)
{
int n = 3;
int [,]mat = { {4, 2, 1},
{3, 9, 6},
{11, 3, 15}};
Console.Write("Largest zigzag sum: " +
largestZigZag(mat, n));
}
}
// This code is contributed by 29AjayKumar
输出:
Largest zigzag sum: 28
参考:Directi中的要求