Algorithm 动态规划:寻找最大三角形
我需要用动态规划在一个由0和1组成的矩阵中找到最大的三角形。如果这是我的矩阵:Algorithm 动态规划:寻找最大三角形,algorithm,dynamic-programming,pseudocode,Algorithm,Dynamic Programming,Pseudocode,我需要用动态规划在一个由0和1组成的矩阵中找到最大的三角形。如果这是我的矩阵: 1 0 0 1 1 0 1 1 1 1 0 1 1 1 0 1 1 1 1 1 1 1 0 0 1 然后有两个最大的三角形,其右角位于[2,2]和[4,4]。我只需要寻找正确的等腰三角形(角度为90◦, 45◦, 45◦) 我只需要看一个方向,因为所有其他方向都是对称的。所以基本上我需要一个函数,它接受矩阵并返回一个三角形,三角形是一个对象。我不需要完整的代码。伪代码对我来说也很好 首先,我想在这里使用平
1 0 0 1 1
0 1 1 1 1
0 1 1 1 0
1 1 1 1 1
1 1 0 0 1
然后有两个最大的三角形,其右角位于[2,2]和[4,4]。我只需要寻找正确的等腰三角形(角度为90◦, 45◦, 45◦) 我只需要看一个方向,因为所有其他方向都是对称的。所以基本上我需要一个函数,它接受矩阵并返回一个三角形,三角形是一个对象。我不需要完整的代码。伪代码对我来说也很好
首先,我想在这里使用平方算法:,当你找到最大的平方,那么最大的三角形一定在那里。但是我可以很容易地找到反例,在这不起作用的地方。在那之后,我试着看上面的单元格,用动态规划来计算,但我不确定下一步该怎么做…所以我的计数在上面的矩阵中,将如下所示:
1 0 0 1 1
0 1 1 2 2
0 2 2 3 0
1 3 3 4 1
2 4 0 0 2
我想我们必须以某种方式使用它
更新:
我想我现在非常接近了,当你遍历矩阵n*m,并使count[I][j]=1+min(count[I-1][j],count[I][j-1]),那么看看左边和上面的单元格。我们得到:
1 0 0 1 1
0 1 1 2 2
0 1 2 3 0
1 2 3 4 1
1 2 0 0 1
这对我来说很好,你可以看到[4,4]解的右角在哪里。有人能想出任何反例吗?我只需要返回一个解,所以返回这个解就可以了
更新2:
我找到了一个反例,让位置[4,4]为0,我们得到以下矩阵:
1 0 0 1 1
0 1 1 1 1
0 1 1 1 0
1 1 1 0 1
1 1 0 0 1
遍历矩阵后,计数将如下所示:
1 0 0 1 1
0 1 1 2 2
0 1 2 3 0
1 2 3 0 1
1 2 0 0 1
现在它将返回带有右角[3,4](第三行第四列)的三角形,这是不正确的,它应该找到[2,2]。因此我认为可能只是从左上角(我们到目前为止所做的)和右下角开始,并从中取最大值。因此,右下角的计数将如下所示(查看下方和右侧的单元格):
现在我们确实找到了[2,2]的解,所以我认为使用这些方法可以得到解,有人能想出更好的解或反例吗
更新3:
kraskevich让我意识到,我们必须使用这个算法四次。从左上角,右上角,左下角,右下角,然后取最大值,因为这样你就得到了所有的可能性。有谁有更好的方法来做到这一点吗?这个算法正确吗?(因此,相同的算法只有四倍,矩阵中只有另一个起点)
另外,对于那些不了解我在做什么的人(我可能会走得有点快),请再看一看:这种方法非常相似,并且很好地解释了所做的事情。免责声明: 我没有仅仅重申OP正在做什么,事实上,我们更新计数的方式是不同的 我同意我应该详细说明解决方案中所述算法有效的原因,因此我编辑了我的答案,以包括我所写方法的关键思想(观察部分) 在我发布我的解决方案时,我完全不知道OP的方法(参见),因此实际上我甚至没有尝试重申OP正在做什么。我只是希望对解决问题的方法给出一个正式的描述 起初,我一直试图避免发布正式的数学正确性证明(因为Stackoverflow主要用于编码),并且我相信从我编写解决方案的方式来看,应该很明显,正确性可以直接从归纳中得出。尽管如此,根据OP的要求,我已经在我的最新更新中包含了完整性证明 ======================================================================== 解决方案
你可以使用与你所引用的帖子类似的方法。为了简单起见,我们只考虑在讨论的左上角找到直角三角形。它应该是直截了当的,以概括我们对其他情况的方法。
我们定义了一个与输入矩阵大小相同的矩阵D
,并将其所有条目初始化为0
。我们希望使用D[i][j]
来表示在(i,j)
处转弯的最大三角形(左上角为直角)的大小
我们的方法基于以下观察结果:
对于在(i,j)
处大小为n
的三角形,有必要在(i+1,j)
和(i,j+1)
处都有大小为(至少)n-1的三角形
我们可以利用这一事实,使用自下而上的方法计算D
。我们将通过多次迭代计算D
,其中在n
第次迭代后,我们将找到大小为n
的所有三角形。我们将根据以下规则更新D
:
在第一步中,如果输入矩阵在(i,j)
处有1
,我们将D[i][j]=1
在n
-th过程中,对于D
中值n-1
的每个条目(假设该条目位于(i,j)
,我们检查D[i+1][j]
和D[i][j+1][/code>是否都等于n-1
,如果是,我们设置D[i][j]=n
当遇到没有更新D
项的过程时,我们终止算法
备注:n
-第次过程实际上找到了大小为n
的三角形的所有位置,我们将使用此信息更新下一次过程,这是动态规划中的关键思想-我们找到了较小子问题的解,并将使用它帮助解决较大尺寸的问题
最大三角形的大小(以及它的位置)可以在b中找到
1 0 0 2 1
0 4 3 2 1
0 3 2 1 0
2 2 1 1 1
1 1 0 0 1
function solve() {
var row, col;
var i = 0;
var n;
var here,above;
for (row = 1 ; row < SIZE ; row++) {
n = grid[0 + SIZE * row];
for (col = 1 ; col < SIZE ; col++) {
here = grid[col + SIZE * row];
if (here > 0) {
if (n > 0) {
above = grid[col + SIZE * (row - 1)];
grid[col + SIZE * row] = 1 + Math.min(n, above);
}
n++;
} else {
n = 0;
}
}
}
}