形成字符串的最小路径

时间:2018-04-14 10:20:24

标签: algorithm dynamic-programming theory

给定符号N x M的矩阵S,并且给定的符号序列找到以给定顺序遍历所有符号的最小路径。允许的路线为UP, DOWN, LEFT, RIGHT

示例:

Matrix:
   123
   265
   346
Sequence:
   1234561
Output:
   8 (start from top left corner, then D, D, R, R, U, L, U, L)

请注意,符号可以重复,因此图形算法在这里没用。 实际路径不相关,只有数字,因此动态编程可能就是这样。

形式上:给定的符号序列必须是路径的子序列。

我正在寻找一种能够找到上述最短路径长度的算法。

2 个答案:

答案 0 :(得分:2)

动态编程状态可以是(row, col, pos):电路板上的两个坐标以及我们构建的序列中的位置。

函数f (row, col, pos)是达到此状态所需的最小总距离。

显然,当matrix[row][col]不等于sequence[pos]时,状态无效。 我们将按f (row, col, pos) = infinity对其进行编码。

对于f (row, col, 1) = 0的位置,基数为matrix[row][col] = sequence[1]

外部循环遍历状态的pos部分。 要在f (row, col, pos)等于matrix[row][col]的情况下查找sequence[pos],我们希望观察所有状态(row', col', pos - 1)并采用f (row', col', pos - 1)的最小值加上距离(row', col') (row, col)|row - row'| + |col - col'|。 此距离仅为f (row, col, n)

答案是n的最小值,其中f (row, col, pos)是序列的长度。

希望你能从这里拿走它。

即使实际路径相关,这种方法也会有所帮助。 为了找到实际路径,我们可以将先前的状态与函数值一起存储。 换句话说,row'可以是三元组:实际答案,前一状态的col',前一状态的class Formatter { ... virtual std::ostream& insert(std::ostream&) const = 0; friend std::ostream& operator<<(std::ostream& os, const Formatter& fmt) { return fmt.insert(os); } }; class Formatter_State1_Mode1: public Formatter { ... std::ostream& insert(std::ostream&) const override; }; class Formatter_State1_Mode2: public Formatter { ... std::ostream& insert(std::ostream&) const override; }; Formatter* makeFormatter(Mode, State, ...);

答案 1 :(得分:2)

当使用f(i, j)矩阵中的s实例时,i代表实现序列前缀的最小距离j,最长为s[i]。角色f(i, j) = min(d(c, j') + f(i - 1, j')) for all j' where d is the distance function c is the jth instance of the character s[i] j' is an instance of the character s[i - 1] 。然后:

O(n * (r * c) * (r * c))

此解决方案的最大复杂度为n,因为序列中有r * c个字符,每个字符最多包含javac Flower.java -Xlint:unchecked 个实例。但对于输入而言,序列中每个字符的矩阵实例数量相对较少,可能会显着提高效率。