数塔取数问题

题目六、数塔取数问题

一个高度为N的由正整数组成的三角形,从上走到下,求经过的数字和的最大值。

每次只能走到下一层相邻的数上,例如从第3层的6向下走,只能走到第4层的2或9上。

5

8 4

3 6 9

7 2 9 5

例子中的最优方案是:5 + 8 + 6 + 9 = 28

Input

第1行:N,N为数塔的高度。(2 <= N <= 500)

第2 - N + 1行:每行包括1层数塔的数字,第2行1个数,第3行2个数......第k+1行k个数。数与数之间用空格分隔(0 <= A[i] <= 10^5) 。

Output

输出最大值

输入示例

4

5

8 4

3 6 9

7 2 9 5

7

7

8 4

3 6 9

7 2 9 5

12 33 4 5 66

23 4 344 55 33 12

23 23 44 90 78 77 99

输出示例

28

492

解题思路:

这题的解题思路第一个大概就是暴力了吧 =。=,先来讲讲暴力的思路。就开一个二维数组存储数字塔,我就从塔顶枚举每一条可能的路径,类似于二叉数,要枚举的路径在2^n级别,考虑n = 500的情况,大概也就10^150的数量级,真是妥妥的超时。

所以就要第二种方法,动态规划。在开一个储存数字塔的二维数组f的同时,也开启一个同样大小的数组dp[][],dp[i][j]表示第i行第j列的元素到底层的最短距离。dp[i][j] = max(dp[ i + 1 ][ j ] , dp[ i + 1 ][ j + 1] ) + f[ i ][ j ],f[i][j]为数字塔的具体元素。时间复杂度就从指数级降到了平方级。

代码:

#include <cstdio>
#include <algorithm>
#define MAXN  510
using namespace std;
int f[MAXN][MAXN], dp[MAXN][MAXN];// 数字塔数组和dp数组
int main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {// 循环输入数字塔
        for (int j = 1; j <= i; j++) {
            scanf("%d", &f[i][j]);
        }
    }
    for (int j = 1; j <=n; j++) {
        dp[n][j] = f[n][j]; // dp数组最底层的元素和数组塔最底层的元素相同,自己到自己的数字之和当然是本身咯
    }
    for (int i = n - 1; i >= 1; i--) {
        for (int j = 1; j <= i; j++) {
            dp[i][j] = max(dp[i + 1][j], dp[i + 1][j + 1]) + f[i][j]; //状态转移方程
        }
    }

    printf("%d\n", dp[1][1]); //dp[1][1]就是从顶层到底层的最大距离,即为所求
    return 0;
}
时间: 2024-08-05 19:36:52

数塔取数问题的相关文章

1002 数塔取数问题

1002 数塔取数问题 基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 一个高度为N的由正整数组成的三角形,从上走到下,求经过的数字和的最大值. 每次只能走到下一层相邻的数上,例如从第3层的6向下走,只能走到第4层的2或9上. 5 8 4 3 6 9 7 2 9 5 例子中的最优方案是:5 + 8 + 6 + 9 = 28 Input 第1行:N,N为数塔的高度.(2 <= N <= 500) 第2 - N + 1行:每行包括1层数塔的数字,第2行1个数,第3

[2016-05-09][51nod][1002 数塔取数问题]

时间:2016-05-09 19:25:06 星期一 题目编号:[2016-05-09][51nod][1002 数塔取数问题] 题目大意: 一个高度为N的由正整数组成的三角形,从上走到下,求经过的数字和的最大值.每次只能走到下一层相邻的数上,例如从第3层的6向下走,只能走到第4层的2或9上. 分析:动态规划 dp[i][j] 表示到 dp[i][j]时的最大值 dp[i][j] = max(dp[i-1][j],dp[i - 1][j - 1]) + a[i][j]; ans = max(dp

数塔取数

1002 数塔取数问题 基准时间限制:1 秒 空间限制:131072 KB 一个高度为N的由正整数组成的三角形,从上走到下,求经过的数字和的最大值. 每次只能走到下一层相邻的数上,例如从第3层的6向下走,只能走到第4层的2或9上. 5 8 4 3 6 9 7 2 9 5 例子中的最优方案是:5 + 8 + 6 + 9 = 28 Input 第1行:N,N为数塔的高度.(2 <= N <= 500) 第2 - N + 1行:每行包括1层数塔的数字,第2行1个数,第3行2个数......第k+1行

动态规划&amp;数塔取数&amp;矩阵取数&amp;背包问题&amp;最大子段和&amp;正整数分组

动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法.在面试笔试中动态规划也是经常作为考题出现,其中较为简单的DP题目我们应该有百分之百的把握顺利解决才可以. 一.动态规划定义动态规划实际上是一类题目的总称,并不是指某个固定的算法.动态规划的意义就是通过采用递推(或者分而治之)的策略,通过解决大问题的子问题从而解决整体的做法.动态规划的核心思想是巧妙地将问题拆分成多个子问题,通过计算子问题而得到整体问题的解.而子

51Nod一级算法1002数塔取数问题

---恢复内容开始--- 1 #include<stdio.h> 2 #include<stdlib.h> 3 #define max(x,y) ((x)>(y)?(x):(y)) 4 int main(){ 5 int n; 6 int i,j,k; 7 scanf("%d",&n);//层数 8 k = (n+1)*n/2;//所有节点总数 9 int *a = (int*) malloc(sizeof(int) * k);//动态数组,记录每

51Nod 1002 数塔取数问题

Input示例 4 5 8 4 3 6 9 7 2 9 5 Output示例 28

HDU 2084 数塔-dp-(数塔)

题意:数字排成三角形,求从顶点加到底,最大的和是多少.每个点只能加跟它直接相连的其中一个 分析: 数塔是经典的dp模型,从底往上推,每次找最大的往上一层加,最后归总到顶点,结果就是顶点的值. dp[i][j]:加到dp[i][j]第i行第j个数时的最大和:dp[i][j]=dp[i][j]+max(dp[i+1][j],dp[i+1][j+1]) 代码: #include<iostream> #define max(a,b) a>b?a:b; using namespace std; i

NOIp模拟3 取数游戏

试题描述 有一个取数的游戏.初始时,给出一个环,环上的每条边上都有一个非负整数.这些整数中至少有一个0.然后,将一枚硬币放在环上的一个节点上.两个玩家就是以这个放硬币的节点为起点开始这个游戏,两人轮流取数,取数的规则如下: (1)选择硬币左边或者右边的一条边,并且边上的数非0: (2)将这条边上的数减至任意一个非负整数(至少要有所减小): (3)将硬币移至边的另一端. 如果轮到一个玩家走,这时硬币左右两边的边上的数值都是0,那么这个玩家就输了.如下图,描述的是Alice和Bob两人的对弈过程,其

P1288 取数游戏II

题目描述 有一个取数的游戏.初始时,给出一个环,环上的每条边上都有一个非负整数.这些整数中至少有一个0.然后,将一枚硬币放在环上的一个节点上.两个玩家就是以这个放硬币的节点为起点开始这个游戏,两人轮流取数,取数的规则如下: (1)选择硬币左边或者右边的一条边,并且边上的数非0: (2)将这条边上的数减至任意一个非负整数(至少要有所减小): (3)将硬币移至边的另一端. 如果轮到一个玩家走,这时硬币左右两边的边上的数值都是0,那么这个玩家就输了. 如下图,描述的是Alice和Bob两人的对弈过程,