动态规划习题:数字三角形

问题描述 
       7 
     3   8 
    8    1    0 
        2     7    4    4 
     4    5    2    6     5 
上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路
径,把路径上面的数加起来可以得到一个和,和最大的路径称为最佳路径。你的任务就是求
出最佳路径上的数字之和。
注意:路径上的每一步只能从一个数走到下一层上和它最近的左边的数或者右边的数。

输入数据
输入的第一行是一个整数 N (1 < N <= 100),给出三角形的行数。下面的 N行给出数字
三角形。数字三角形上的数的范围都在 0和 100之间。



我们形象的描述下这个问题,把每一层的数字,描述为金子数量,那么我们就是要选择一条最优的路径,获得最大的金子数量。

思路:从第0层到最后4层来递归,当我在第0层,思考往左还是往右的时候,实际上这就是一个选择,类似0,1背包的放还是不放。那么第一层的最优解=往左走的最优解和往右走的最优解中的最大值+第0层的金子,那么这里也就产生了两个最优子结构,所以可以得出状态转移方程:f(i,j)=max(f(i+1,j),f(i+1,j+1))+Tri[i][j]

 1 #include <iostream>
 2 using namespace std;
 3 int mydp[5][5];
 4 int Tri[5][5]={{7},
 5               {3,8},
 6              {8,1,0},
 7             {2,7,4,4},
 8            {4,5,2,6,5}};
 9 int get_max37(int a,int b)
10 {
11     return a>b?a:b;
12 }
13 int max_sum(int i,int j)
14 {
15     int retMax;
16     if(mydp[i][j]!=-1)
17     {
18         retMax=mydp[i][j];
19     }
20     //边界条件
21     else if(i==4)
22     {
23         retMax=Tri[i][j];
24     }
25     else
26     {
27          retMax=get_max37(max_sum(i+1,j),max_sum(i+1,j+1))+Tri[i][j];
28     }
29     mydp[i][j]=retMax;
30     return retMax;
31 }
32 int main()
33 {
34     for (int i=0;i<5;++i)
35     {
36         for (int j=0;j<5;++j)
37         {
38             mydp[i][j]=-1;
39         }
40     }
41     cout<<max_sum(0,0);
42     system("pause");
43     return 0;
44 }
时间: 2024-09-30 15:52:13

动态规划习题:数字三角形的相关文章

动态规划入门-数字三角形(从朴素递归到各种优化)

数字三角形(POJ1163) Description 73 88 1 02 7 4 44 5 2 6 5 在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大.路径上的每一步都只能往左下或右下走.只需要求出这个最大和即可,不必给出具体路径.三角形的行数大于1小于等于100,数字为 0 - 99 输入格式:5 //三角形行数.下面是三角形73 88 1 02 7 4 4 4 5 2 6 5 要求输出最大和 Sample Output 30 Source IOI 1994

动态规划_数字三角形

问题描述:在下面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大,路径上的每一步都只能往左下或右下走.只需要求出这个最大和即可,不必给出具体路径. 输入数据的要求:三角形的行数大于1小于等于100,数字为0--99. 输入格式: 5 //三角形的行数,下面是三角形 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 #include <iostream> using namespace std; const int N = 101; int a[N][N], n

动态规划之数字三角形

题目大意: 有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外每个数的左下方和右下方各有一个数,如图 1 3  2 4  10  1 4  3  2  20 从第一行的数开始,每次可以往左下或右下走一格,直到走到最下行,把沿途经过的数全部加起来,如何走才能使得这个和尽量大. #include <cstdio> #include <iostream> using namespace std; const int MAX = 1001; int data[MAX][MAX]

【动态规划】数字三角形

原题传送门 思路 这道题在CODEVS上标签是动态规划,然而本蒟蒻想了半天也没想出来(可能是我还是太弱了......),于是打算写个大爆搜看看能混几分,于是,20分钟的时间码完DFS,交上去,AC??!话说这道题数据这么不给力的吗???数据这么小那还用个什么DP啊???浪费发际线,然而,动态规划是绝对要比爆搜快的,如果数据够大,爆搜是无法AC的,而且毕竟做这道题的本意是练习动态规划,所以我又想了想动态规划的思路,最终动态规划的代码也做出来了,AC~~~ DFS-Code #include<ios

POJ_3176_Cow_Bowling(数字三角形)

描述 http://poj.org/problem?id=3176 给出一个三角形,每个点可以走到它下面两个点,将所有经过的点的值加起来,问最大的和是多少. 分析 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using std :: max; 5 6 const int maxn=355; 7 int a[maxn][maxn],f[maxn][maxn]; 8 int n; 9 10 i

2018.01.01(数字三角形,最长上升子序列等)

2017.12.24  简单的动态规划 1.数字三角形(算法引入) 题目描述:下图所示是一个数字三角形,其中三角形中的数值为正整数,现规定从最顶层往下走到最底层,每一步可沿左斜线向下或右斜线向下走.设三角形有n层,编程计算出从顶层到底层的一条路径,使得该路径上的和最大,输出最大值.(n<=100) 思路&&代码(搜索回溯): #include <stdio.h> #include <math.h> #include <string.h> int m

JDOJ 1606 数字三角形

JDOJ 1606: 数字三角形 JDOJ传送门 Description 输入n,输出n的数字三角形 见样例 Input n Output n的数字三角形 Sample Input 4 Sample Output 1 1 2 1 2 3 1 2 3 4 题解: 这回可不是动态规划的数字三角形. 是...真的数字三角形. 看代码学吧. 代码: #include<cstdio> #include<cstring> #include<cmath> #include<io

[动态规划]数字三角形

动态规划一直是一个很头疼的问题啊. 最近在看这方面的东西,记录一下刘汝佳书里的动态规划章节里的数字三角形题目. 这道题很基础,但总结的三个动态规划很清晰. 有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外每个数的左下方和右下方各有一个数,形如: 1 3 2 4 10 1 4 3 2 20 每个结点都可到它左右子结点,例如3可以到4也可以到10. 从第一行开始每次可以往左下或右下走一格,直到走到最下,把沿途结点的值相加,如何走才能得到最大值. 如果遍历的话,n层会有2的n次方种可能性

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

1. 问题描述 有一个像这样的数字三角形: 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 从顶点开始,每个数字向下层走只能有左下和右下两个方向,求出到达最后一行时最大的路径之和. Input 第1 行是数字三角形的行数n,1<= n <=100. 接下来n行是数字三角形各行中的数字.所有数字在0---99之间. 比如Input是: 5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 则output是30. 2. 问题求解 这是一个典型的动态规划求解问题,因为它符合动态