您当然可以一次处理一列。
然后要将列[x1, x2, x3, ...]
转换为列[y1, y2, y3, ...]
,您有几种情况:
- case (A):
x1
is the same as y1
: 这是简单的情况,你需要匹配其余的
- case (B):
x1
is -
and y1
is not: 你需要插入所有剩余的y
盒子
- 案例(C):
y1
是-
和x1
不是:您需要删除所有剩余的x
框
- 案例(D):
x1
并且y1
不是空的而是不同的;在这里你必须选择:(D1)翻转x1
并匹配[x2,...]
, (D2 )[y2,...]
删除x1
并匹配[x2, ...]
。[y1, ...]
您应该选择(D1)或(D2),具体取决于哪个需要较少的操作。
y1
注意:根据规则,插入x
和匹配选项(D3)不可[x1,...]
用[y2,...]
,因为您只能在堆的顶部添加框(案例 B)。
这转化为动态编程(或带有记忆的递归)算法:
int min_moves(int i, int j);
并且您需要计算将列x[i], x[i+1], ...
与列对齐的移动次数,y[j], y[j+1], ...
其中x
和y
是从文件中读取的两个清单的原始内容,假设x[i]
和y[i]
为-
any i>m
。
要计算min_moves(i, j)
,您可以使用min_moves(i+1, j+1)
(case A+D1), min_moves(i+1, j)
(case D2)。案例 B 和 C 不需要递归,而是直接计算x
和y
。