对具有多个检查点的网格中的路径进行计数
Count paths in a grid with multiple checkpoints
给定大小为N X N
的网格。其左下角点为(0,0)
,右上角元素为(N-1,N-1)
。
我们可以在顶部或右侧穿过网格。我们必须找到从左下角到右上角的遍历方法的数量有一些检查点我们必须在每条路径上访问。至少有一个有效路径。
示例:设N=5
,我们在(2,2)
有一个检查点,那么这里的答案是36
。
注意:我只需要计算有效路径,而不需要担心找到它们
什么是有效的计数方法?
您必须知道两件事:
-
乘积法则:表示从起点到终点的路数等于从起点到中点的路数*从中点到终点的路数。
-
C(R,R+U)(
R
是你向右移动的次数,U
是向上移动的次数——这意味着如果你想从(a,b)
到(c,d)
,那么R = c-a
、U = d-b
和C(R,R+U) = (R+U)!/R!U!
)是网格中从左下到右上有多少种方式的答案。
示例在您的示例中,根据我的第二条规则,我们有:
从(0,0)
移动到(2,2)
的次数,因为从0
向右移动两次之后到达2
,从0
向上移动两次后到达2
,因此到达R=2
,U=2
,因此达到C(2,2+2) = C(2,4) = 4!/2!2! = 6
。对R
和U
做同样的操作,从(2,2)
到(4,4)
的移动次数是C(2,2+2) = C(2,4) = 4!/2!2! = 6
根据第一条规则,我们得到了所有可能的移动次数:6 * 6 = 36
使用动态编程:
dp[k, i, j] = number of paths from checkpoint k to (i, j)
dp[k, i, j] = dp[k, i - 1, j] + top
dp[k, i, j - 1] right
答案是检查点之间dp
值的乘积。
注意:您可以通过意识到矩阵中的实际位置并不重要,只需要位置和检查点位置之间的相对距离来避免第一维。
这个特殊问题的关键是找到子点之间的路径数(根据它们各自的位置排序后),然后乘以所有路径数。
这里的解决方案是:
1.从"源"到"目标"对点进行排序
示例:如果起点是[0,0],终点是[10,10],中间点是[5,6],[2,4]&[8,8],则排序的点(包括源和目的地)将是11X11矩阵中的[0,0]、[2,4]、[5,6]、[8,8]、[10,10]
2.查找从源到下一个子目的地的路径数(最好使用DP)。(按排序点的顺序)
在上面的例子中,需要计算的路径数量将在以下点之间:
[0,0]至[2,4]
[2,4]至[5,6]
[5,6]至[8,8]
[8,8]至[10,10]
3.查找以上4个子路径的乘积
就是
这里有一个从源和目的地查找路径数的解决方案(请参阅DP方法)。您不需要将矩阵作为参数传递,因为这是不需要的。只需要形式为[x,y][x,y]的源点和目标点。除了链接中的代码外,其他部分(对点进行排序和相乘)必须如上所述进行
- 如何将更多文件夹添加到c++include路径
- 带有特殊路径部分的"std::filesystem::weakly_canonical"失败
- C++A*算法并不总是在路径中具有目标节点
- 从函数角度看ID到文件路径的内部与外部映射
- 如何从 Skia 路径几何体中获取网格?
- 用于查找网格中最短路径的算法
- 如何使用条件计算 3D 网格中从一个点到另一个点的所有路径
- 在网格中找到大多数K移动和最高分数的路径
- 如何在C 中完全遍历5x5网格以产生相同长度的路径(25)
- 使用路径调查访问网格中的所有节点
- 如何在网格上找到从A到B的最短路径
- 对具有多个检查点的网格中的路径进行计数
- 到网格所有点的最短路径
- 使用动态规划计算网格中的路径数
- 4x4 网格 c++ 上的最短路径
- 在C++中查找2D网格中长度为L的所有路径
- 如果可能的话,使用递归在网格中查找路径
- 路径查找(在网格中)与Boost图形库
- 网格中的最佳路径
- 查找网格上唯一路径的数量