我目前正在尝试解决problem 18 of project Euler。目标是:
从下方三角形的顶部开始,移动到下面一行的相邻数字,从上到下的最大总数为23。
3 7 4 2 4 6 8 5 9 3即3 + 7 + 4 + 9 = 23。
查找下方三角形从上到下的最大总数:
75 95 64 17 47 82 18 35 87 10 20 04 82 47 65 19 01 23 75 03 34 88 02 77 73 07 63 67 99 65 04 28 06 16 70 92 41 41 26 56 83 40 80 70 33 41 48 72 33 47 32 37 16 94 29 53 71 44 65 25 43 91 52 97 51 14 70 11 33 28 77 73 17 78 39 68 17 57 91 71 52 38 17 14 91 43 58 50 27 29 48 63 66 04 68 89 53 67 30 73 16 69 87 40 31 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23
我尝试使用以下算法解决它:
public static void main(String[] args) throws NumberFormatException, IOException {
int[][] values = readFile();
int depth = values.length - 2;
while ( depth >= 0) {
for (int j = 0; j < depth; j++) {
values[depth][j] += Math.max( values[depth+1][j], values[depth+1][j+1]);
}
depth += -1;
}
values[0][0] += Math.max(values[1][0], values[1][1]);
System.out.println("The maximum path sum is: " + values[0][0]);
}
数组值包含三角形中的所有数字,其中values[0][0]
是顶行中的元素,values[n][n]
是最后一行中的最后一个元素。
该算法使用的方法是,例如,如果我从最后一行开始并且在04 + 63和62 + 63之间进行选择,那么63所在的字段的总和将被设置为125,因为这是最高的量。该算法适用于小三角形,但对于大三角形,它似乎失败了。我不确定为什么并且会欣赏每一个提示。
答案 0 :(得分:4)
我相信这一行:
for (int j = 0; j < depth; j++) {
应该是
for (int j = 0; j <= depth; j++) {
因为您现在没有访问每一行的最后一个元素。当然,那么你不需要行
values[0][0] += Math.max(values[1][0], values[1][1]);
因为它已经在循环中完成了。
答案 1 :(得分:3)
我不知道正确的算法,但有一个简单的证据证明@Johns对这个问题的评论,最好的本地选择并不一定能带来最佳的全球解决方案。
考虑这个(极端)例子:
1 1 0 1 0 1000 1 0 0 0 1 0 0 0 0
根据你的算法,你显然会走在路径的最左边,从不读取必须在最佳路径上的1000。
答案 2 :(得分:0)
这可能不是最好的解决方案,但是如果每次迭代都跟踪到该点的总和。然后,当你到最后一行时,最大值将是你的答案。