关闭

ACM—动态规划-数塔

151人阅读 评论(0) 收藏 举报
分类:

HDU 2084

一、题目

在讲述DP算法的时候,一个经典的例子就是数塔问题,它是这样描述的:有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?

输入

输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数,且所有的整数均在区间[0,99]内。

输出

 

 对于每个测试实例,输出可能得到的最大和,每个实例的输出占一行。


 

二、思路

该题有两种解题思路:

1.     顺推法

从数塔的顶部向下推,每个数(除去边界)向上有两个分支,比较上面两个分支数(指的是加完后的新的数塔)的大小,哪个数大就将那个数再加到本位置上面,直到最后一层。则最大的数字之和就是最后一行中最大的那个数。

其动态规划方程为:

F[0][0] = A[0][0];

F[i][0] = F[i-1][0]+A[i][0];

F[i][i] = F[i-1][i-1]+A[i][i];

F[i][j] = max{F[i-1][j-1],F[i-1][j]}+A[i][j];

最终答案为max{F[n-1][j],0<=j<=n-1};

2.     逆推法

从数塔的最低一层开始向上推,比较相邻的两个数(加完后的数)的大小,哪个数大就加到上一层中的那个数上面,直到加到最上面一层,则最大的数就是第一层的那个数。

其动态规划方程为:

G[n-1][j] = A[n-1][j]  0<=j<=n-1;

G[i][j] = max{G[i+1][j],G[i+1][j+1]}+A[i][j];

最后答案为G[0][0];

 

三、代码实现

1.顺推法

#include<stdio.h>
#define N 100
int A[N][N];
int F[N][N];
 
int main()
{
    int i,j,n;
    scanf("%d",&n);
    for(i = 0; i < n; i++)
        for(j = 0; j <= i; j++)      //注意j是从0到i,而不是从0到n-1
            scanf("%d",&A[i][j]);  //将数塔存入A[N][N]数组中。
    F[0][0] = A[0][0];          //边界处理
    for(i = 1; i < n; i++)
        for(j = 0; j < n; j++)
        {
            if(j == 0)
                F[i][j] = A[i][j] + F[i - 1][j];   //边界处理
            else if(j == i)
                F[i][j] = A[i][j] + F[i - 1][j - 1];   //边界处理
            else
            {
                if(F[i - 1][j - 1] > F[i - 1][j])      //动态规划方程核心
                    F[i][j] = F[i - 1][j - 1] + A[i][j];
                else
                    F[i][j] = F[i - 1][j] + A[i][j];
            }
        }
    int max = F[n - 1][0];
    for(j = 1; j < n; j++)       //求最大值MAX
        if(max < F[n - 1][j]) max = F[n - 1][j];
    printf("%d\n",max);
    return 0;
}

2.逆推法

#include<stdio.h>
#define N 100
int A[N][N];
int G[N][N];
 
int main()
{
    int i,j,n;
    scanf("%d",&n);
    for(i = 0; i < n; i++)
        for(j = 0; j <= i; j++)    //注意j是从0到i,而不是从0到n-1
            scanf("%d",&A[i][j]);    //将数塔存入A[N][N]数组中。
    for(j = 0; j < n; j++)         //边界处理
        G[n - 1][j] = A[n - 1][j];
    for(i = n - 2; i >= 0; i--)      //注意i的范围
        for(j = 0; j <= i; j++)
        {
            if(G[i + 1][j] > G[i + 1][j + 1])
                G[i][j] = G[i + 1][j] + A[i][j];
            else
                G[i][j] = G[i + 1][j + 1] + A[i][j];
        }
    printf("%d",G[0][0]);      //结果就是G[0][0]
    return 0;
}


0
0
查看评论

杭电(hdu)ACM 2084 数塔

数塔 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 27978   ...
  • IT142546355
  • IT142546355
  • 2015-08-10 10:24
  • 1109

动态规划:数塔问题

动态规划问题我训练过一些题目,但是感觉自己掌握的还不是特别好! 下面以一道经典的动态规划题目说明动态规划算法的思想,文末会官方的给出对动态规划的文字叙述。先看题目:如下图(图片来自百度图片)是一个数塔,从顶部出发在每一个节点可以选择向左或者向右走,一直走到底层,要求找出一条路径,使得路径上的数字之...
  • T_27080901
  • T_27080901
  • 2015-05-17 23:35
  • 12997

动态规划简单例子(数塔问题)java

问题描述:     从数塔的顶层出发,在每一个结点可以选择向左走或者向右走,一直走到最底层,要求找出一条路径,使得路径上的数值和最大。 解题思路:      先求解初始子问题:底层的每个数字可以看作1层数塔,则最大数值和就是其自身。 ...
  • zSean
  • zSean
  • 2017-05-26 17:02
  • 694

动态规划 数塔问题求解 C++实现

/* * File name : digital_tower.cpp * Function : 动态规划 数塔问题求解 C++实现 * Created on : 2016年6月17日 * Author : beijiwei@qq.com * Copyright : 欢迎大家和我一起...
  • beijiwei
  • beijiwei
  • 2016-06-17 10:51
  • 1461

杭电ACM 2084 数塔 (动态规划初步)

http://acm.hdu.edu.cn/showproblem.php?pid=2084 用递归的方法实现动态规划,状态转移方程。 效率低下,重复计算了好多! //不能AC #include using namespace std; int a[110][110]; int d(...
  • xujinsmile
  • xujinsmile
  • 2012-08-07 21:29
  • 3773

动态规划----数塔问题

动态规划(Dynamic Programming,简称DP)是通过组合子问题的解来解决问题的。 注意这里的programming不是指编程,而是指一种规划 适用于子问题不是独立的情况,也就是各子问题包含公共的子子问题,鉴于会重复的求解各子问题,DP对每个问题只求解一遍,将其保存在一张...
  • wy19910326
  • wy19910326
  • 2012-02-02 19:47
  • 2374

动态规划算法之数塔问题

一、问题描述 从数塔顶层出发,每个结点可以选择向左走或向右走,要求一直走到塔底,使得走过的路径上的数值和最大。 如上图所示的数塔,最大路径和为86,经过的路径从塔顶到塔底为13,8,26,15,24。 二、问题分析 动态规划函数为: resultTower[i][j] = tower[i][j]...
  • tterminator
  • tterminator
  • 2016-03-21 23:12
  • 5462

51nod 数塔取数问题 —— 动态规划

1002 数塔取数问题 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题  收藏  关注 一个高度为N的由正整数组成的三角形,从上走到下,...
  • u013575812
  • u013575812
  • 2015-12-09 20:26
  • 1141

动态规划-数塔路径之和最大值及路径输出问题

Description 考虑在下面被显示的数字金字塔。 写一个程序来计算从最高点开始在底部任意处结束的路径经过数字的和的最大。 每一步可以走到左下方的点也可以到达右下方的点。 7 3 8 8 1 0 2 7 4 4 4...
  • xianglunxi
  • xianglunxi
  • 2013-07-24 15:39
  • 3446

动态规划——数塔问题

有如下所示的数塔,要求从顶层走到底层,若每一步只能走到相邻的结点,则经过的结点的数字之和最大是多少?
  • cike110120
  • cike110120
  • 2014-05-29 17:56
  • 3962
    个人资料
    • 访问:16459次
    • 积分:453
    • 等级:
    • 排名:千里之外
    • 原创:29篇
    • 转载:5篇
    • 译文:0篇
    • 评论:2条
    文章分类
    最新评论