【发布时间】:2015-09-27 11:18:45
【问题描述】:
我正在尝试计算在网格中从左列到右列可以实现的最大总和。允许的运动是向上、向下、向右。我已经实现了这个解决方案(它是广度优先搜索):
for(int i=1; i<=n; i++) {
Queue<Position> q = new LinkedList<Position>();
q.add(new Position(i, 1));
dp[i][1] = map[i][1];
while(!q.isEmpty()) {
Position node = q.poll();
visited[node.n][node.m] = 1;
if(dp[node.n][node.m] > max) {
max = dp[node.n][node.m];
}
if(visited[node.n-1][node.m] != 1 && node.n != 1 && dp[node.n-1][node.m] < dp[node.n][node.m] + map[node.n-1][node.m] && map[node.n-1][node.m] != -1) {
dp[node.n-1][node.m] = dp[node.n][node.m] + map[node.n-1][node.m];
q.add(new Position(node.n-1, node.m));
}
if(visited[node.n+1][node.m] != 1 && node.n != n && dp[node.n +1][node.m] < dp[node.n][node.m] + map[node.n+1][node.m] && map[node.n+1][node.m] != -1) {
dp[node.n +1][node.m] = dp[node.n][node.m] + map[node.n+1][node.m];
q.add(new Position(node.n + 1, node.m));
}
if(visited[node.n][node.m+1] != 1 && node.m != m && dp[node.n][node.m+1] < dp[node.n][node.m] + map[node.n][node.m+1] && map[node.n][node.m+1] != -1) {
dp[node.n][node.m+1] = dp[node.n][node.m] + map[node.n][node.m+1];
q.add(new Position(node.n, node.m+1));
}
}
}
static class Position {
int n, m;
public Position(int row, int column) {
this.n = row;
this.m = column;
}
}
示例输入:
-1 4 5 1
2 -1 2 4
3 3 -1 3
4 2 1 2
我的解决方案的问题是它应该通过遵循 4->3->3->2 达到 2(在最后一行第 2 列),但我的解决方案将 2 置于已访问状态,因此它不会检查它。如果我删除访问过的数组,它将被困在任何单元格的上、下、上、下无限循环中。
编辑:每个点只能访问一次。
【问题讨论】:
-
4->3->3->2没有到达最后一列。你能澄清一下问题陈述吗? -
相关:stackoverflow.com/q/32679720/572670 不过好像你有不同的招式。
-
2 在位置 (4,2),可以通过 4->2 和 4->3->3->2 达到,但我想要一个具有最大点数的,所以它应该达到有第二种选择。问题是在达到 4->2 后,它会将 2 设置为已经访问过,因此 4->3->3 不会考虑将 2 作为下一个位置
-
另外,如果您允许上、下、右 - 您可以根据需要多次使用循环(如果它是上下循环),并获得“更好”的分数。如果您只寻找简单路径(没有循环),这是最长路径问题,即NP-Hard。
-
只是为了澄清你允许的动作; “上”和“下”实际上是指“右上”和“右下”,对吗?否则,正如阿米特指出的那样,您可以有无限长的解决方案。
标签: algorithm data-structures graph dynamic-programming