我有一个n x n
数组。每个字段都有与之相关的成本(自然数),我在这里是我的问题:
我从第一栏开始。我需要按照以下两条规则找到最便宜的方式来遍历数组(从第一列中的任何字段到最后一列中的任何字段):
k
(某些常数)移到底部。我在单元格x
时的意思我可以移动到这些单元格o
:
如何找到最便宜的阵列移动方式?我想到了这个:
- 对于n x n
数组的每个字段,我保留一个有用的数组,说明在最便宜的路径中到达那里需要多少底部移动。对于第一列,它全部为0。
- 我们遍历此orded中的每个字段:从左到右的列和从上到下的行。
- 对于每个领域,我们检查他们的哪个邻居是最便宜的'。如果它是上一个(意味着我们必须采取一条最低路线从他那里获得),我们检查是否需要k
底部动作才能找到他,如果不是,那么我们分配获得的成本分析字段作为字段顶部+字段的成本之和,并且在对应于字段的记录的辅助数组中,将底部移动的数量设置为x + 1,其中x是底部移动的数量我们走上了他的上层。
- 如果上邻居不是最便宜的,我们将另一个最便宜的邻居的成本和底部移动的数量分配给我们去找他的移动次数。
时间复杂度为O(n^2)
,内存也是如此。
这是对的吗?
答案 0 :(得分:0)
以下是O(N^2)
时间和O(N)
内存中的DP解决方案: -
Dist(i,j) = distance from point(i,j) to last column.
Dist(i,j) = cost(i,j) + min { Dist(i+1,j),Dist(i,j+1),Dist(i+1,j+1),Dist(i-1,j+1) }
Dist(i,N) = cost[i][N]
Cheapest = min { D(i,0) } i in (1,M)
此DP等式表明您只需要下一行的值来获取当前行,因此O(N)
空间可用于维护先前的计算。它还表明需要首先评估同一列中较高的行值。
伪代码: -
int Prev[N],int Curr[N];
// last row calculation => Base Case for DP
for(i=0;i<M;i++)
Prev[i] = cost[i][N-1];
// Evaluate the rows and columns in descending manner
for(j=N-2;j>=0;j--) {
for(i=M-1;i>=0;i--) {
Curr[i][j] = cost[i][j] + min ( Curr[i+1][j],Prev[i][j+1],Prev[i-1][j+1],Prev[i+1][j+1] )
}
Prev = Curr
}
// find row with cheapest cost
Cheapest = min(Prev)