oj3134:动态规划——数字金字塔

Description

7
3   8
8   1   0
2   7   4   4
4   5   2   6   5

(Figure 1)

Figure 1 shows a number triangle. Write a program that calculates the highest sum of numbers passed on a route that starts at the top and ends somewhere on the base. Each step can go either diagonally down to the left or diagonally down to the right.

Input

Your program is to read from standard input. The first line contains one integer N: the number of rows in the triangle. The following N lines describe the data of the triangle. The number of rows in the triangle is > 1 but <= 100. The numbers in the triangle, all integers, are between 0 and 99.

Output

Your program is to write to standard output. The highest sum is written as an integer.

Sample Input

5
7
3 8
8 1 0 
2 7 4 4
4 5 2 6 5

Sample Output

30先来说说我解题的思路:
其实仔细分析整个题目你就会发现:我们可以分步求出每一层上的数字位置处最大值,而这个最大值等于这个数加上其左上角和右上角两个数所在位置的最大值(因为该题的规则某一位置上的数只可以加上其左上角或右上角的数),这样只要从第一层往下推每次都求出该位置上的最大值,最后可以求出塔顶到每一位置的数字之和的最大值,这也正是动态规划解题的方式,每步求出走到当前位置的代价,而后该步的成果作为下一步的基础进行下一步的规划。
  
  仔细观察这个金字塔:我们从第二行开始记录每一位置的“代价”,处于左腰的数字 其当前最大值就是该值与其右上角的数字的“最大值”之和,对应右腰上的最大值为其左上角的最大值与自身之和,其余位置的“最大值”为其左上角两数字对应位置的“最大值”的较大值,最终在检索一遍最下一行的最大值就是所有路径的最大值
代码:

/*
问题描述:递归基础题:数字三角形
作者:何知令
完成时间:2017年5月10日
*/
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int n;
    int i,j;
    scanf("%d",&n);
    int num[n][n];
    int max;
    int sum[n][n];
    for(i=0; i<n; i++)
    {
        for(j=0; j<=i; j++)
            scanf("%d",&num[i][j]);
    }
    sum[0][0]=num[0][0];
    for(i=1; i<n; i++)
    {
        for(j=0; j<=i; j++)
            if(j==0)
                sum[i][j]=sum[i-1][0]+num[i][j];//数字在左腰的情况
            else if(j==i)
                sum[i][j]=sum[i-1][i-1]+num[i][j];//数字在右腰的情况
            else//余下的普通情况
            {
                max=sum[i-1][j-1];
                if(sum[i-1][j]>sum[i-1][j-1])
                    max=sum[i-1][j];
                sum[i][j]=num[i][j]+max;
            }
    }
    max=sum[n-1][0];
    for(j=0; j<n; j++)
    {
        if(sum[n-1][j]>max)
            max=sum[n-1][j];
    }
    printf("%d",max);
    return 0;
}

程序运行结果展示:


知识点总结:动态规划

学习心得:其实懂了以后动规也就没那么可怕了

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值