C 单调路径区域的递归和
我试图找到一种递归的方法来找到从nxn网格的左上角到右下角(路径的每一步可以沿直线向右或向下)的所有单调路径的所有区域的总和 假设左下角有坐标(0,0),我有以下函数:C 单调路径区域的递归和,c,recursion,path,area,C,Recursion,Path,Area,我试图找到一种递归的方法来找到从nxn网格的左上角到右下角(路径的每一步可以沿直线向右或向下)的所有单调路径的所有区域的总和 假设左下角有坐标(0,0),我有以下函数: int sum(int current_sum, int x, int y, int n){ if (x == n || y == 0) return current_sum; return (sum(current_sum+y, x+1, y, n) + sum(current_sum,
int sum(int current_sum, int x, int y, int n){
if (x == n || y == 0)
return current_sum;
return (sum(current_sum+y, x+1, y, n) + sum(current_sum, x, y-1, n));
}
,在到达网格右侧或底线时停止(从网格右侧移动不会改变区域的当前值),并考虑向右或向下移动所产生的区域总和。结果比应该的要大,我很难找出原因。有人能看一下吗
提前感谢再次阅读,OP的解决方案似乎已经正确了。下面是我的答案供参考。
这似乎是ProjectEuler,或者一个非常类似的问题 如果我理解正确,你想做的是:
int area(int x, int y)
{
if (x == 0 || y == 0)
/* We are at the end of a path, terminate */
return 0;
/* We are not at the end, add the two choices possible from here */
return area(x, y - 1) + area(x - 1, y) + y;
}
你必须画一个图来确认最后一个表达式是正确的。当我们在网格(-x)中向右移动时,我们只在总和上加y,这样就覆盖了我们下面的一列。向下移动(-y)不会覆盖任何区域
此解决方案应该是正确的,但速度会非常慢。为了加快速度,您可以添加记忆,这意味着将区域(x,y)的中间结果保存到表中,并查找它,而不是每次都计算它。我不会为您编写解决方案,但这并不难做到。祝你好运
[…]从nxn栅格的左上角到右下角[…]
您的代码不反映以下情况:
// ...
if (x == n || y == 0)
return current_sum;
// ...
想象一条完全水平的路径。例如,在2对3网格中,当索引以0
开始,且左下角为(0 | 0)
,则右下角为(1 | 0)
。现在考虑右上角,即<代码>(1×2)< /代码>。对于这些值,上述两个条件都不成立,因此您将对接下来两个单元格的递归调用求和:(2 | 2)
(向右)和(1 | 1)
(向下)
第一个单元格(向右)就是问题所在:在那里,x==2==n
,因此返回路径的和,尽管它没有在右下角结束。因此,对太多路径求和,导致总体求和过大
我认为这应该做到:
unsigned sum_inner(
unsigned const accumulatedSum,
size_t const x, size_t const y,
size_t const gridSideSize) {
bool atRightEdge = (x == gridSideSize - 1);
bool atBottomEdge = (y == 0);
if (atRightEdge && atBottomEdge) {
// Awesome, in lower right corner, so everything is fine
// Except that with the implementation of the other two edge cases, this
// will never be run (except for the 1x1 case)!
printf("reached lower right edge!\n");
return accumulatedSum + 1;
} else if (atRightEdge) {
// Right edge, so from here one can only go down. Since there's only one
// possible path left, sum it directly:
return accumulatedSum + y + 1;
} else if (atBottomEdge) {
// Bottom edge, so from here one can only go right. Since there's only one
// possible path left, sum it directly:
return accumulatedSum + (gridSideSize - x) + 1;
} else {
// Somewhere in the grid, recursion time!
return sum_inner(accumulatedSum + y, x + 1, y, gridSideSize) +
sum_inner(accumulatedSum, x, y - 1, gridSideSize);
}
}
unsigned sum_monotonic_tl_br(size_t const gridSideSize) {
return sum_inner(0, 0, gridSideSize - 1, gridSideSize);
}
我认为,添加一个包含输入、预期和实际输出的具体示例会有很大帮助。这是Euler项目的一个问题:关注回报。x+1,y-1。使用2步循环,x从低到高,y从高到低,怎么样?它可以绕过移动到零值墙。相关: