有效地在矩阵中找到其元素总和为目标数的路径? [关闭]
Posted
技术标签:
【中文标题】有效地在矩阵中找到其元素总和为目标数的路径? [关闭]【英文标题】:Efficiently finding a path in a matrix whose elements sum to a target number? [closed] 【发布时间】:2019-06-19 17:29:31 【问题描述】:编程问题
输入: m x n 严格正数矩阵,目标数 T。
输出: 从入口 (0,0) 开始并在底行结束的简单路径。我们只能在任何给定步骤向右或向下移动。此外,路径元素的总和必须恰好为 T。没有额外的约束。
我已经实施了正确的蛮力解决方案,但我们谈论的是指数时间。是否存在更有效的解决方案(可能使用动态规划)?
我看到了一个类似的现有问题,但答案有限,有人声称这个问题是 NP-Complete,但我无法验证这一点: Finding a path whose elements sum up to a given number in a matrix
【问题讨论】:
这些路径是否允许重用网格单元? 欢迎来到 Stack Overflow。请阅读the help pages,获取the SO tour,了解how to ask good questions,以及this question checklist。最后学习如何创建minimal reproducible example。 "是否存在更有效的解决方案" 不,这是一个非常明显的 NP 完全问题。子集和很容易减少到它。取一组数字。创建一个 2×2N 的矩阵,将零放在左列,将集合中的交替零和数字放在右列。如果你能找到一条总和为 T 的路径,你就能找到一个总和为 T 的子集。 这个问题与您链接的问题有何不同?为了澄清答案,也许更好地评论答案。 @CharlesDupont 首先请更新您的问题,您只能向右和向下移动。这个非常重要。其次,如果我们在谈论一些效率,请为我们提供对n
、m
和T
的一些限制。
【参考方案1】:
如果你只能像你在Efficiently finding a path in a matrix whose elements sum to a target number? 所说的那样向下或向右移动,那么O(nmT)
有一个解决方案:
// let a be given matrix
// d is 3-dimensional matrix: d[X-position][Y-position][sum]
vector<vector<vector<bool>>> d(n, vector<vector<bool>(m, vector<bool>(T + 1, false)));
// initialize dynamics
if (a[0][0] < T)
d[0][0][a[0][0]] = true;
// calcualte dynamics
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (i == 0 && j == 0) // already calculated
continue;
for (int k = 0; k <= T; k++)
bool isPossible = false;
int prevSum = k - a[i][j];
if (i > 0 && prevSum >= 0)
isPossible |= d[i - 1][j][prevSum]; // step down
if (j > 0 && prevSum >= 0)
isPossible |= d[i][j - 1][prevSum]; // step right
d[i][j][k] = isPossible;
如果每个i
的d[n][i][T]
之一是true
(遍历底行),则路径存在,否则不存在。
恢复路径也不是那么难,如果d[i - 1][j][sum - a[i][j]]
为真(或i
为0
)则向上,否则离开。
UPD。这种方法不适用于负数。
UPD2。如果有人告诉如何初始化已知大小的 n 维向量,那就太好了。
【讨论】:
以上是关于有效地在矩阵中找到其元素总和为目标数的路径? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章