数塔问题【递推算法】
关于输入:本题输入一个正整数n,然后输入n行数字,其中第i行有i个数字。例如:
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
本题输入的三角数组形状如下图1,在处理数据时按图2形状来处理。在上面的输入案例中,可以按图3所示数塔来处理。
图1 图2 图3
问题需求:从数塔顶层到底层的某处所经过的路径可能有很多条。本题要求计算所有路径中,各节点数之和最大的那条路径的节点数之和。(注意:只要求输出节点数总和最大的那条路的节点数之和,不是要寻找那条路径。)
另外:从上往下走时,每一步可以沿着左斜线或右斜线走。
关于数据规模:整个数塔的行数n<=100.数塔中的数字a[i][j] ∈ [0,99].
算法分析:
本题不需要寻找路径,可以简单地递推即可得到解答.
试想,从上往下走时,每一步都面临左和右的选择。为了得到最大总和,在看不见更深层的数据时,都应该按照贪心策略,从左和右两边中选比较大的那一边作为向下一层行走的路线。这是正向思路,比较好理解。但这样一来,路径太多,很难找到解答。我们可以考虑逆向递推。既然每一步都选择较大的那一边,那么我们可以假设a[i][j]表示从i,j出发到达底层的最大值。那么就有递推公式:a[i][j]=max{ a[i][j]+a[i+1][j] , a[i][j]+a[i+1][j+1] }.如此一来,a[1][1]就是我们要找的值。
代码如下:
1 #include <stdio.h> 2 int main() 3 { 4 int n,a[201][201]; 5 int i,j; 6 7 scanf("%d",&n);//输入n 8 for(i=1;i<=n;i++)//输入数塔 9 { 10 for(j=1;j<=i;j++) 11 { 12 scanf("%d",&a[i][j]); 13 } 14 } 15 16 for(i=n-1;i>0;i--)//从倒数第2层开始逆推每一层每一个元素到底层的最大值 17 { 18 for(j=1;j<=i;j++) 19 { 20 if(a[i+1][j]>a[i+1][j+1]) a[i][j]+=a[i+1][j]; 21 else a[i][j]+=a[i+1][j+1]; 22 } 23 } 24 printf("%d\n",a[1][1]);//输出从顶层到底层的最大值 25 return 0; 26 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App