Количество путей в матрице

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); 
}