Количество путей в матрице
A p x q
размер матрицы задается, и матрица размера a x b
удаляется из верхнего правого угла. Найдите полное нет. путей от верхнего левого к нижнему правому, С только правыми и вниз разрешенными движениями. Ни один путь не должен входить в удаленную матрицу.
, например,
_
|_|_
|_|_|
это (2x2)
матрица после удаления (1x1)
матрица из верхнего правого угла. нет. из способов -5
.
Я могу узнать общее количество путей, но метод я мышление об устранении путей, которые идут в удаленную часть, очень элементарно и, следовательно, неэффективно.
Итак, есть ли лучший алгоритм для этого ?
3 ответов
вы можете использовать структуру таблицы:
количество путей от одного угла к другому на квадратной сетке задается размером сетки треугольником Паскаля:(x+y) choose x
каждый путь должен пересекать ровно одну точку на каждой диагонали.
возьмите все точки по диагонали, проходящей через внутренний угол, вычислите количество путей через каждый и суммируйте.
Это приводит к O(min(p-a, q-b))
алгоритм, предполагающий постоянное время арифметика.
в вашем случае: (два пути к центру) * (два пути от центра) + (один путь через угол) = (четыре пути через центр) + (один путь через угол) = (пять путей)
+-+-+
| | |
+-+-A-+-+
| | | | |
+-B-+-+-+
| | | | |
C-+-+-+-+
| | | | |
+-+-+-+-+
(1+2) choose 1 * (2+3) choose 2 (through A)
+ (2+1) choose 2 * (3+2) choose 3 (through B)
+ (3+0) choose 3 * (4+1) choose 4 (through C)
= 3 choose 1 * 5 choose 2
+ 3 choose 2 * 5 choose 3
+ 3 choose 3 * 5 choose 4
= 3*10
+ 3*10
+ 1*5
= 30+30+5 = 65 paths
сделать топологическая сортировка на Даг1 представление проблемы.
затем повторите от последнего (раковина) до первого (источник):
f(v) = Sum(f(u)) for each (v,u) in E
base: f(sink) = 1
сложность линейна по размеру графа (повторяя каждую вершину ровно один раз) (используя размеры матрицы это O(p*q-a*b)
)
(1) граф G=(V, E) равен:
V = { (i,j) | for each i,j in the matrix that was not deleted }
E = { ((i1,j1),(i2,j2)) | (i1,j1) is to the left/up of (i2,j2) }
//assume we are moving from m,n to 1,1
int numberOfPaths(int m, int n)
{
/*If the m,n is left-bordered to the removed matrix, then move only downwards
till the end of removed matrix,then we can move in two directions*/
//l1=numberOfrows(bigMatrix)-numberOfRows(smallMatrix), similarly l2 for columns
if(m==l1&&n>=l2)
return numberOfPaths(l1-1,l2+2)+numberOfPaths(l1,l2+1);
// If either given row number is first or given column number is first
if (m == 1 || n == 1)
return 1;
return numberOfPaths(m-1, n) + numberOfPaths(m, n-1);
}