编程问题
输入: m x n严格为正数的矩阵,目标值为T。
输出:一个简单的路径,从条目(0,0)开始到最后一行。在任何给定步骤中,我们只能向右或向下移动。此外,路径元素必须总计为T。没有其他约束。
我已经实施了正确的蛮力解决方案,但是我们正在谈论指数时间。是否存在更有效的解决方案(也许使用动态编程)?
我看到了一个类似的现有问题,但是答案是有限的,有人声称这个问题是NP-Complete,但是我无法验证这一点: Finding a path whose elements sum up to a given number in a matrix
答案 0 :(得分:0)
如果您只能按照此处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;
}
如果每个d[n][i][T]
的{{1}}之一是i
(在最下面的行中重复),则路径存在,否则不存在。
恢复路径也不是那么困难,只要true
为真(或d[i - 1][j][sum - a[i][j]]
为i
)就可以了,否则就保留。
UPD。这种方法不适用于负数。
UPD2。如果有人告诉我们如何初始化已知大小的n维向量(不是那么奇怪),那就太好了。