找到棋盘上的棋子可以随着移动的数量和类型移动的方式的数量

时间:2013-06-20 23:52:20

标签: algorithm dynamic-programming chess

这是我在网站上遇到的动态编程问题。我用下面提到的算法解决了这个问题。虽然我得到的答案是正确的,但评估表明时间限制超过了。

问题是,在N * N板上,一块位于(xp,yp)位置。当且仅当abs(xd-xp)+ abs(yd-)时,它可以移动到(xd,yd) yp)< = S.这件作品必须让M动作。这个问题给出了N,S,M和(xp,yp),我必须找到这个棋子在这个棋盘上移动的方式。

我的解决方案如下。

Matrix m0 is initialized with all 0s except with 1 in the location (xp,yp)

Make a N*N matrix m1 for one move from an initialized matrix m0

Make a N*N matrix m2 for two moves from matrix m1

... carry on till m moves and the sum of elements of the final matrix mm 
gives me the number of ways the piece can make M moves on the N*N board 
with given distance constraint S.

我的计算矩阵的伪代码如下

for each element (e) in matrix m, 

consider the elements (es) in S*S (S is the distance constraint 
given in the problem) box surrounding the elements.

If (abs(es.x-e.x) + abs(es.y-e.y)) <= S, 
then m[e.x][e.y] = m[e.x][e.y] + m[es.x][es.y]. 

(adding the # of ways that es can be reached with number of ways that e can be reached 
 so that position of e in the matrix contains # of ways that e can be reached from es)

In the S*S box, I considered all  elements except the current element e.

根据我的理解,上述解决方案是(N ^ 2)*(S ^ 2)并且运行缓慢但它给出了正确的答案。请提出在N ^ 2时间实现此功能的想法。由于它涉及2D板,我认为它不能在O(N)时间内完成,但我可能错了。

1 个答案:

答案 0 :(得分:0)

此类问题的关键是使用滑动窗口重用部分结果。

例如,假设您知道数组X的元素1到1000的总和是1234,并且想要知道元素2到1001的总和。快速的方法是计算1234 + X [1001] -X [ 1]。

在此问题中,您对绝对值的约束意味着您尝试以菱形形状添加所有值。

如果我们现在将窗口向对角滑动一步,我们可以通过添加左下角的值来计算新的总和,并取消左上角的值:

..A..    ..-..   .....
.AAA.    .--A.   ...B.
..A.. -> ..A++ = ..BBB
.....    ...+.   ...B.

在图中,我们添加了标有+的值,并删除了标有 - 。

的值

这减少了从O(S ^ 2)到O(S)的操作次数,以计算每个新值。

然而,您可以做得更好,因为您可以使用相同的技巧来预先计算沿每个对角线的值的总和。然后,您可以使用O(1)计算每个新值。