描述:
有一个像这样的数字三角形:
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
从顶点开始,每个数字向下层走只能有左下和右下两个方向,求出到达最后一行时的最大路径之和.
算法和思路:
设三角形的行数为level (level = (sqrt(1 + 8 * LENGTH) - 1) / 2),可以采用顺推的方法,先求出第二行到第一行的最大路径和,然后再依次的求出第3,4,.......n - 1,n到第一行的最大路径和.
程序的设计方面,采用开辟两个一维数组的方法.一个存储原来的数字三角形的数据,另一个存储每行的每个元素的最大路径和(就是起点到此点的最大路径和).最后比较最后一行的元素,最大值就是最大路径和.
源代码:
#include
<
stdio.h
>
#include
<
math.h
>
#define
LENGTH 15
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
returnmax(
int
a,
int
b)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
return (a > b ? a : b);
}
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
int
digitalTriangle(
int
P[])
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int max, level, pointlevel, i, j, left, right;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
int P1[LENGTH]; /**//* 记录每个点的最大路径和 */
max = 0;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
level =(-1 + sqrt(1 + 8 * LENGTH)) / 2; /**//* 计算共有多少层 */
for(i = 0; i < LENGTH; i++)
P1[i] = 0;
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
for(pointlevel = 1; pointlevel <= level; pointlevel++) /**//* 计算每个节点的权值 */
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
//pointlevel = i; /* 定义节点的层 */
left = (pointlevel) * (pointlevel - 1) / 2;
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
right = left + pointlevel - 1; /**//* 定义三角形边上的点 */
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
for(j = left; j <= right; j++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
...{
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
if(j == left) /**//* 处理左边节点 */
P1[j] = P1[j - pointlevel + 1] + P[j];
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
else if(j == right) /**//* 处理右边节点 */
P1[j] = P1[j - pointlevel] + P[j];
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
else /**//* 处理中间节点 */
P1[j] = returnmax(P1[j - pointlevel + 1], P1[j - pointlevel]) + P[j];
}
}
for(i = 0; i <= level; i++)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
max = returnmax(max,P1[LENGTH - 1 - level + i]); /**//* 挑选最大的路径和 */
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
return max;
}
int
main()
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
...
{
int i;
int A[LENGTH];
int maxsum;
printf("Please input 15 numbers: ");
for(i = 0; i < LENGTH; i++)
scanf("%d",&A[i]);
maxsum = digitalTriangle(A);
printf(" The Max sum is: %d",maxsum);
return 0;
}
最后要多谢coconut的帮助,让我理解了动态规划的思想.
"动态规划是说算的时候要多次用到子问题,把子问题的结果存下来,这样可以减少算的次数,所以叫空间换时间。。。"