Problem 1004 Number Triangle

Accept: 2230    Submit: 5895
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

Consider the number triangle shown below. Write a program that calculates the highest sum of numbers that can be 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.

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

In the sample above, the route from 7 to 3 to 8 to 7 to 5 produces the highest sum: 30.

 Input

There are multiple test cases.The first line of each test case contains R (1 <= R <= 1000), the number of rows. Each subsequent line contains the integers for that particular row of the triangle. All the supplied integers are non-negative and no larger than 100.

 Output

Print a single line containing the largest sum using the traversal specified for each test case.

 Sample Input

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

 Sample Output

30

很明显的一道动归题,类似于求最大路径,方法有很多,搜索啊,递归啊,,,但用动归是最简单的,动归思路有两种:

1:

用二维数组存放数字三角形;

D( r, j) : 第r行第 j 个数字(r,j从1 开始算)

MaxSum(r, j) : 从D(r,j)到底边的各条路径中最佳路径的数字之和,问题是就求MaxSum(1,1);
典型的递归问题
D(r, j)出发,下一步只能走D(r+1,j)或者D(r+1, j+1)。故对于N行的三角形:
if ( r == N)
MaxSum(r,j) = D(r,j)
else
MaxSum( r, j) = Max{ MaxSum(r+1,j), MaxSum(r+1,j+1) } + D(r,j);

2: 如果每算出一个MaxSum(r,j)就保存起来,下次用到其值的时候直接取用,则可免去重复计算。

那么可以用 O(n2)时间完成计算。因为三角形的数字总数是 n(n+1)/2;这时,递归转化为递推;

下面呈现两种思路代码:

1:超时代码:

#include <iostream>
#include <algorithm>
#define MAX 101
using namespace std;
int D[MAX][MAX];
int n;
int MaxSum(int i, int j){
if(i==n)
return D[i][j];
int x = MaxSum(i+,j);
int y = MaxSum(i+,j+);
return max(x,y)+D[i][j];
}
int main(){
int i,j;
cin >> n;
for(i=;i<=n;i++)
for(j=;j<=i;j++)
cin >> D[i][j];
cout << MaxSum(,) << endl;
}
如果采用递规的方法,深度遍历每条路径,存在大量重复计算。则时间复杂度为 2n, 对于 n = 100行,肯定超时。

  2:记忆递归

#include <iostream>
#include <algorithm>
using namespace std;
#define MAX 101
int D[MAX][MAX]; int n;
int maxSum[MAX][MAX];
int MaxSum(int i, int j){
if( maxSum[i][j] != - )
return maxSum[i][j];
if(i==n) maxSum[i][j] = D[i][j];
else {
int x = MaxSum(i+,j);
int y = MaxSum(i+,j+);
maxSum[i][j] = max(x,y)+ D[i][j];
}
return maxSum[i][j];
}
int main(){
int i,j;
cin >> n;
for(i=;i<=n;i++)
for(j=;j<=i;j++) {
cin >> D[i][j];
maxSum[i][j] = -;
}
cout << MaxSum(,) << endl;
}

3:

#include <iostream>
#include <algorithm>
using namespace std;
#define MAX 101
int D[MAX][MAX]; int n;
int maxSum[MAX][MAX];
int main() {
int i,j;
cin >> n;
for(i=;i<=n;i++)
for(j=;j<=i;j++)
cin >> D[i][j];
for( int i = ;i <= n; ++ i )
maxSum[n][i] = D[n][i];
for( int i = n-; i>= ; --i )
for( int j = ; j <= i; ++j )
maxSum[i][j] = max(maxSum[i+][j],maxSum[i+][j+]) + D[i][j]
cout << maxSum[][] << endl;
}
人人为我”递推型动归程序

4:当然了,3中的代码也可以空间优化,从下往上找

#include <iostream>
#include <algorithm>
using namespace std;
#define MAX 101
int D[MAX][MAX];
int n; int * maxSum;
int main(){
int i,j;
cin >> n;
for(i=;i<=n;i++)
for(j=;j<=i;j++)
cin >> D[i][j];
maxSum = D[n]; //maxSum指向第n行
for( int i = n-; i>= ; --i )
for( int j = ; j <= i; ++j )
maxSum[j] = max(maxSum[j],maxSum[j+]) + D[i][j];
cout << maxSum[] << endl;
}
如果看不懂简单手推模拟一遍你就明白了,不难。。和3中代码类似,只是将二维转化为一维了;

FZU1004-Number Triangle经典动归题,核心思路及代码优化的更多相关文章

  1. 6581 Number Triangle

    6581 Number Triangle 时间限制:500MS  内存限制:1000K提交次数:57 通过次数:47 题型: 编程题   语言: G++;GCC Description 7 3 8 8 ...

  2. JAVA经典算法40题及解答

    JAVA经典算法40题 [程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分 ...

  3. JAVA经典算法40题

    1: JAVA经典算法40题 2: [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 3 ...

  4. JAVA经典算法40题(原题+分析)之分析

    JAVA经典算法40题(下) [程序1]   有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?   1.程序分析:  ...

  5. JAVA经典算法50题(转)

    转载请注明出处:http://blog.csdn.net/l1028386804/article/details/51097928 JAVA经典算法50题 [程序1]   题目:古典问题:有一对兔子, ...

  6. JAVA经典算法40题面向过程

    JAVA经典算法40题 [程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分 ...

  7. java经典算法40题-附带解决代码

    前一段时间工作比较闲,每天没有代码敲的日子有点无聊,于是为了保证自己的编程逻辑力的日常清醒,故百度了一些经典的java算法,然后自己思考编程解决问题,虽然那些东西比较基础了,但是有些题目小编看到了也是 ...

  8. UVA 674 Coin Change 换硬币 经典dp入门题

    题意:有1,5,10,25,50五种硬币,给出一个数字,问又几种凑钱的方式能凑出这个数. 经典的dp题...可以递推也可以记忆化搜索... 我个人比较喜欢记忆化搜索,递推不是很熟练. 记忆化搜索:很白 ...

  9. JAVA经典算法40题(原题+分析)之原题

    JAVA经典算法40题(上) [程序1]   题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? [程 ...

随机推荐

  1. Coco dfs 或者 状压dp。...

    C -- Coco Time Limit:1s Memory Limit:64MByte Submissions:148Solved:85 DESCRIPTION Coco just learned ...

  2. AJPFX总结java InputStream读取数据问题

    1. 关于InputStream.read()     在从数据流里读取数据时,为图简单,经常用InputStream.read()方法.这个方法是从流里每次只读取读取一个字节,效率会非常低.     ...

  3. AJPFX总结内部类

    内部类:内部类的访问规则:1. 内部类可以直接访问外部类中的成员,包括私有   原因是内部类中持有了一个外部类的引用,格式:外部类.this2. 外部类要访问内部类,必须建立内部类对象访问格式:1.  ...

  4. python绘图工具包 matplotlib 中文乱码问题

    环境: python2.7 windows 8.1 解决: 改配置文件,把字体改为支持中文的字体. 找到python安装目录下的 \Lib\site-packages\matplotlib\mpl-d ...

  5. xutils3批量上传文件

    前几天开发安卓要用到文件批量上传,就是上传图片,视频,文件之类的用到Xutil3框架,用 RequestParams params = new RequestParams(url); params.a ...

  6. hdu 2192 MagicBuilding

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  7. vSphere Client用户名密码保存记录

    vSphere Client在访问ESXi主机或vCenter后是默认不保存登录用户名和密码的,不过可以通过修改配置文件来保存,方便访问连接. 方法如下: 打开配置文件路径(实际安装路径):D:\Pr ...

  8. iview table 已选项的数据 this.$refs.tables.$refs.tablesMain.getSelection()

    iview table 已选项的数据 this.$refs.tables.$refs.tablesMain.getSelection() 由于我这里table组件是套了两层组件 所以是进入了两个层次拿 ...

  9. ROI(Region of Interesting)

    ROI(region of interest),感兴趣区域.机器视觉.图像处理中,从被处理的图像以方框.圆.椭圆.不规则多边形等方式勾勒出需要处理的区域,称为感兴趣区域,ROI.在Halcon.Ope ...

  10. 洛谷——P1627 [CQOI2009]中位数

    P1627 [CQOI2009]中位数 给出1~n的一个排列,统计该排列有多少个长度为奇数的连续子序列的中位数是b.中位数是指把所有元素从小到大排列后,位于中间的数. 中位数的题目有关统计的话,可以转 ...