这是关于最大L和的first question,这里有不同的硬版本。
问题:给定 mxn 正整数矩阵,找到第1行到第m行<的最小L和< / strong>。 L(4项)喜欢象棋移动
示例:M = 3x3
0 1 2
1 3 2
4 2 1
可能的L动作是:(0 1 2 2),(0 1 3 2)(0 1 4 2) 我们应该从第1 行到第3 行,最小总和
我用动态编程解决了这个问题,这是我的算法:
1. 取一个mxn另一个最小L移动和数组并复制主矩阵的第一行。我称之为(MLMS)
2。从第一个细胞开始,然后查看向上L移动并计算它
3. 如果小于存在值,则将其插入MLMS
4. 执行步骤2.直到 m'th 行
5. 选择 m'th 行中的最小金额
让我一步一步地解释我的例子:
M [0] [0] 和(L1 =(0,1,2,2))= 5;和(L2 =(0,1,3,2))= 6;所以MLMS [0] [1] = 6
和(L3 =(0,1,3,2))= 6;和(L4 =(0,1,4,2))= 7;所以MLMS [2] [1] = 6
M [0] [1] 和(L5 =(1,0,1,4))= 6;和(L6 =(1,3,2,4))= 10;所以MLMS [2] [2] = 6
...
最后一个MSLS是:
0 1 2
4 3 6
6 6 6
这意味着6是从0到m的最小L和。
我认为它是 O(8 *(m-1) n)= O(m n)。是否有适合此问题的最佳解决方案或动态编程算法?
谢谢,抱歉很长的问题
答案 0 :(得分:1)
如何在总共0-th
行的矩阵中同时显示m-th
和m
行?
无论如何,一个简单的Dijkstra将为您提供O(n*m)
中的最佳路径(假设您有一个良好的数据结构,可以在尚未到达的点列表中找到最小值)。
另外,如果你的骑士只能向下移动(有时向上移动以减少总路径重量),你可以编写简单的DP。从电路板底部开始,每个位置计算到达底部所需的电量。由于每个位置最多可以进行4次移动,因此最简单的检查是最简单的。像这样的东西
for (int row = m - 1; row >= 0; --row) {
for (int col = 0; col < m; ++col) {
int path1 = a[row][col + 1] + a[row][col + 2] + a[row + 1][col + 2] + best[row + 1][col + 2];
int path2 = a[row][col + 1] + a[row + 1][col + 1] + a[row + 2][col + 1] + best[row + 2][col + 1];
int path3 = ...
int path4 = ...
best[row][col] = min(path1, path2, path3, path4);
}
}
修改强>
你为什么要上去?想象一下这样的矩阵(其中*
意味着一些可笑的大数字,比如1000000000)。显然,在你离开之前,你必须从(0, 0)
转到董事会的右边。
111111111111
111111111111
*********111
*********111
所以,路径看起来像这样
...1...1...1
11...1...1..
*********11.
*********11.