Я бы решал через DP, то есть
- создал бы массив той же размерности
- в каждой ячейке массива писал бы сумму всех произведений, что в этой ячейке заканчиваются.
То есть изначальный массив
[1, 0, 0]
[1, 1, 0]
[0, 1, 0]
[0, 0, 2]
DP массив поначалу забитый нулями
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]
[0, 0, 0]
Первый столбец от 0 строки до len-2 строки просто проставляем равным изначальнму (первые шаги путей)
[1, 0, 0]
[1, 0, 0]
[0, 0, 0]
[0, 0, 0]
Второй столбец от 1 строки до len-1 строки - суммируем все возможные произведения для второго столбца
[1, 0, 0]
[1, 1, 0]
[0, 1*1+1*1, 0]
[0, 0, 0]
Третий столбец от 2 строки до len строки - делаем то же самое для третьего столбца (тут важно понимать, что для нахождения сумм третьего столбца нам нужен только второй столбец, первый уже не нужен)
[1, 0, 0]
[1, 1, 0]
[0, 2, 0]
[0, 0, 2*1 + 2*2]
Суммируем третий столбец (там уже все суммы произведений всех путей для каждой ячейки)
[1, 0, 0]
[1, 1, 0]
[0, 2, 0]
[0, 0, 6]
сумма третьего столбца = 6
Вот и всё по сути. Поскольку на каждой итерации мы для каждой ячейки перебираем весь следующий стоблец (N*N), и таких переборов у нас будет столько, сколько столбцов (M), то суммарная сложность алгоритма будет M*N*N
(то есть M*(N**2)
)
Код на C# (я питонов ваших не умею) получился бы примерно такой
int SumOfMult(int[,] data)
{
int N = data.GetLength(0);
int M = data.GetLength(1);
var dp = new int[N, M];
for (int i = 0; i < N; i++)
{
dp[i, 0] = data[i, 0];
for (int j = 0; j < M - 1; j++)
for (int k = i + 1; k < N; k++)
dp[k, j + 1] += data[k, j + 1] * dp[i, j];
}
int ret = 0;
for (int i = 0; i < N; i++) ret += dp[i, M - 1];
return ret;
}
Сложность вышла MNN, но если чуть чуть подшаманить, можно получить NNN при условии, если M>N
Проверка
Console.WriteLine(SumOfMult(new[,] {
{ 1, 0, 0 },
{ 1, 1, 0 },
{ 0, 1, 0 },
{ 0, 0, 2} }));
Вывод
6