动态规划----数字三角形

描述:

有一个像这样的数字三角形:
         

                    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

int  returnmax( int  a, int  b)
{
    
return (a > b ? a : b);
}


int  digitalTriangle( int  P[])
{
    
int max, level, pointlevel, i, j, left, right;
    
int P1[LENGTH]; /* 记录每个点的最大路径和 */
    max 
= 0;
    level 
=(-1 + sqrt(1 + 8 * LENGTH)) / 2/* 计算共有多少层 */
    
for(i = 0; i < LENGTH; i++)
        P1[i] 
= 0;

    
for(pointlevel = 1; pointlevel <= level; pointlevel++)     /* 计算每个节点的权值 */
    
{
        
//pointlevel = i;   /* 定义节点的层 */
        left = (pointlevel) * (pointlevel - 1/ 2;
        right 
= left + pointlevel - 1;        /* 定义三角形边上的点 */

        
for(j = left; j <= right; j++)
        
{
            
if(j == left)  /* 处理左边节点 */
                P1[j] 
= P1[j - pointlevel + 1+ P[j];
            
else if(j == right)  /* 处理右边节点 */
                P1[j] 
= P1[j - pointlevel] + P[j];
            
else             /* 处理中间节点 */
                P1[j] 
= returnmax(P1[j - pointlevel + 1], P1[j - pointlevel]) + P[j];
        }

    }

    
    
for(i = 0; i <= level; i++)
        max 
= returnmax(max,P1[LENGTH - 1 - level + i]); /* 挑选最大的路径和 */

    
return max;
}

    
        
int  main()
{
    
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的帮助,让我理解了动态规划的思想.

"动态规划是说算的时候要多次用到子问题,把子问题的结果存下来,这样可以减少算的次数,所以叫空间换时间。。。"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值