`
MouseLearnJava
  • 浏览: 460265 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

[动态规划] 数字三角形问题(一维数组实现)

阅读更多
数字三角形问题:一个数字三角宝塔。设数字三角形中的数字为不超过100的正整数。现规定从最顶层走到最底层,每一步可沿左斜线向下右斜线向下走。假设三角形行数小于等于100.编程求解从最顶层走到最底层的一条路径,使得沿着该路径所经过的数字的总和最大,输出最大值

例如一个行数为5的三角形如下:
               7
             3   8
           8   1   0
         2   7   7   4
       5   5   2   6   5


这一个问题,很容易想到用枚举的方法去解决,即列举出所有路径并记录每一条路径所经过的数字总和。然后寻找最大的数字总和,这一想法很直观,也比较容易实现。不过,缺点是:当行数很大时,比如行数等于100,其枚举量是相当巨大的。

这是一个多阶段决策性的问题--> 最优路径上的每一个数字开始的向下的路径也是该数字到最下层的最优路径,符合最优化原理,可以考虑用动态规划的方法实现。

本文采用一维数组去求解数字三角形问题,并用上述行数为5的三角形作为实例来求解。

/**
 * 
 * @author Eric
 *
 */
public class TriangleProblem {

	/**
	 * 使用一维数组结合动态规划思想求解数字三角形问题。
	 * @param array 存储三角形数字的一维数组(从上到下,从左到右存储)
	 * @param n 数字三角形的行数
	 * @return 返回一个经过路径的数字的总和最大值
	 */
	public int populateMaxSum(int[] array, int n) {
		int[] result = new int[array.length];
		
		for (int row = 0; row < n; row++) {
			if (row == 0) {
				/*
				 * 设置定点的值 
				 */
				result[0] = array[0];
			} else {
				int rowStartIndex = populateStartRowIndex(row);
				
				/*
				 * 设置第row行第一个位置到顶点的最大值只有一个。
				 * 直接赋值。
				 */
				result[rowStartIndex] = array[rowStartIndex]
						+ result[rowStartIndex - row];

				for (int col = 1; col <= row; col++) {
					
					if (col < row) {
						/*
						 * 处理到顶点的数值有两个节点的位置,
						 * 取大的那一个。
						 */
						result[rowStartIndex + col] = max(result[rowStartIndex
								- row + col - 1]
								+ array[rowStartIndex + col],
								array[rowStartIndex + col]
										+ result[rowStartIndex - row + col]);
					} else {
						
						/*
						 * 每行最右边的的位置到顶点的最大值也只有一个。
						 * 此时 row == col
						 * 直接赋值。
						 */
						result[rowStartIndex + col] = result[rowStartIndex
								- row + col - 1]
								+ array[rowStartIndex + col];
					}

				}
			}
		}
		/*
		 * 当所有的位置到顶点的位置都计算出来之后,
		 * 要计算出最大值,只要计算最大行中最大值即可。
		 * 
		 */
		return max(populateStartRowIndex(n - 1), result);
	}

	/**
	 * 根据一个指定的行号,计算出在一维数组中对应的下标,最为该行的起始下标
	 * @param row 行号(从0开始)
	 * @return
	 */
	private int populateStartRowIndex(int row) {
		int sum = 0;
		for (int i = 0; i <= row; i++) {
			sum += i;
		}
		return sum;
	}

	private int max(int startIndex, int[] array) {
		int max = array[startIndex];

		for (int i = startIndex; i < array.length; i++) {
			if (array[i] > max) {
				max = array[i];
			}

		}
		return max;
	}

	private int max(int v1, int v2) {
		return (v1 > v2) ? v1 : v2;
	}
}


测试代码==>
public class Main {

	public static void main(String[] args) {
		TriangleProblem tp = new TriangleProblem();
		int[] array = { 7, 3, 8, 8, 1, 0, 2, 7, 4, 4, 4, 5, 2, 6, 5 };
		System.out.printf("最大和为 SUM=%d", tp.populateMaxSum(array, 5));
	}
}

输出结果==>
最大和为 SUM=30

当然,我们可以将三角形中的数据保存到文件中,然后读取文件的内容,再将这些数字初始化到一维数组中去,这里就不再展开。

比如,将三角形数据存在到一个txt文件中,数字之间用空格隔开
7
3 8
8 1 0
2 7 7 4
5 5 2 6 5
... ...

转载请注明出处:http://mouselearnjava.iteye.com/blog/1964219
2
0
分享到:
评论

相关推荐

    动态分割 数字三角形

    数字三角形中的数字为不超过100的整数。现规定从最顶层走到最底层,每一步可沿左斜线向下或右斜线向下走。  任务一:假设三角形行数≤10,键盘输入一个确定的整数值M,编程确定是否存在一条路径,使得沿着该路径所...

    使用python打印十行杨辉三角过程详解

    杨辉三角,是二项式系数在三角形中的一种几何排列 每个数等于它上方两数之和。 每行数字左右对称,由1开始逐渐变大。 第n行的数字有n项。 第n行数字和为2n-1。 第n行的m个数可表示为 C(n-1,m-1),即为从n-1个...

    C++程序设计综合练习题-程序设计题.doc

    利用函数将一维数组中各元素按从大到小的顺序排列输出。 10. 输入任意一个字符串,将其中的大写字母转换成小写字母。 11. 使用枚举常量编写一个程序。从键盘输入1个月份值(1~12),输出该月份属于哪个 季节。 12....

    javascript入门笔记

    特点 :将 a 和 b 转换为 二进制,按位比较,对应位置的数字,至少有一位为1的话,那么该为的整体结果就为1,否则为 0 ex : 5 | 3 101 011 ======== 111 结果为 :7 适用场合:任何小数与0 做 按位或的操作...

    leetcode推箱子-dynamic-planning:动态规划

    求一维数组中不重叠的两个子数组的最大和(求两个子数组最大的累加和) 动态规划-最短路径 动态规划-背包问题 f(i,j) = Max{ f[i-1,j-W[i]]+P, f[i-1,j] (j &lt;W[i]) } f[i,j]表示在前i件物品中选择若干件放在承重为 ...

    C语言实例解析精粹

    012 用一维数组统计学生成绩 013 用二维数组实现矩阵转置 014 求解二维数组的最大/最小元素 015 利用数组求前n个质数 016 编制万年历 017 对数组元素排序 018 任意进制数的转换 019 判断回文数 020 求数组前...

    220个C语言程序源代码集合.zip

    012 用一维数组统计学生成绩 013 用二维数组实现矩阵转置 014 求解二维数组的最大/最小元素 015 利用数组求前n个质数 016 编制万年历 017 对数组元素排序 018 任意进制数的转换 019 判断回文数 020 求数组前...

    leetcode三角形打印-LeetCode-classify:用于归类总结其中的一类题型

    二维数组中的查找 5. 替换空格 6. 从尾到头打印链表 7. 重建二叉树(前、中;前、后;中、后) 9.二个栈实现队列 10.1 斐波那契数列 10.2 青蛙跳台阶问题 11. 旋转数组的最小数字 12. 矩阵中的路径 13. 机器人的运动...

    220个C语言程序源代码.zip

    012 用一维数组统计学生成绩 013 用二维数组实现矩阵转置 014 求解二维数组的最大/最小元素 015 利用数组求前n个质数 016 编制万年历 017 对数组元素排序 018 任意进制数的转换 019 判断回文数 020 求数组前...

    Java经典编程源码基础例程300.zip

    实例031 获取一维数组的最小值 44 实例032 将二维数组中的行列互换 45 实例033 利用数组随机抽取幸运观众 47 实例034 用数组设置JTable表格的 列名与列宽 49 实例035 使用按钮控件数组实现 计算器界面 51 实例036 ...

    200个C程序.rar

    012 用一维数组统计学生成绩 013 用二维数组实现矩阵转置 014 求解二维数组的最大/最小元素 015 利用数组求前n个质数 016 编制万年历 017 对数组元素排序 018 任意进制数的转换 019 判断回文数 020 求数组前...

    220个经典C程序源码文件,可以做为你的学习设计参考.zip

    012 用一维数组统计学生成绩 013 用二维数组实现矩阵转置 014 求解二维数组的最大/最小元素 015 利用数组求前n个质数 016 编制万年历 017 对数组元素排序 018 任意进制数的转换 019 判断回文数 020 求数组前...

    上海电机学院C语言实训答案

    提示:可考虑用两个一维数组实现学生成绩和学生信息的存储。 (19)歌手大赛评分 某歌手大赛,共有十个评委给选手打分,分数采用百分制,去掉一个最高分,去掉一个最低分,然后取平均分,得到歌手的最后成绩。 ...

    200个经典C程序【源码】

    012 用一维数组统计学生成绩 013 用二维数组实现矩阵转置 014 求解二维数组的最大/最小元素 015 利用数组求前n个质数 016 编制万年历 017 对数组元素排序 018 任意进制数的转换 019 判断回文数 020 求数组前...

    LeetCode解题总结

    13. 动态规划 13.1 三角形从顶到底的最小路径和 13.2 最大连续子数组 13.3 字符串的所有子回文字符串 13.4 最长公共子序列问题 13.5 字符串的编辑距离 13.6 不同路径之和 13.6.1 无障碍13.6.2 有障碍 13.7 最大矩形...

    杨辉三角c语言程序实现

    杨辉三角是一种数学上的三角形,其特点是每一行的数字都是上一行相邻两个数字之和。C语言程序用于生成杨辉三角。它首先接收用户输入的杨辉三角行数,然后使用嵌套循环计算每一行的数值,并将结果存储在一个二维数组...

    C语言经典源代码实例 数据结构 操作系统 图形等

    012 用一维数组统计学生成绩 013 用二维数组实现矩阵转置 014 求解二维数组的最大/最小元素 015 利用数组求前n个质数 016 编制万年历 017 对数组元素排序 018 任意进制数的转换 019 判断回文数 020 求数组前...

    C语言源代码实例.rar

    012 用一维数组统计学生成绩 013 用二维数组实现矩阵转置 014 求解二维数组的最大/最小元素 015 利用数组求前n个质数 016 编制万年历 017 对数组元素排序 018 任意进制数的转换 019 判断回文数 020 求数组前...

    经典的C程序220案列

    012 用一维数组统计学生成绩 013 用二维数组实现矩阵转置 014 求解二维数组的最大/最小元素 015 利用数组求前n个质数 016 编制万年历 017 对数组元素排序 018 任意进制数的转换 019 判断回文数 020 求数组前...

    关于C的精粹包含至少200个C语言小程序

    012 用一维数组统计学生成绩 013 用二维数组实现矩阵转置 014 求解二维数组的最大/最小元素 015 利用数组求前n个质数 016 编制万年历 017 对数组元素排序 018 任意进制数的转换 019 判断回文数 020 求数组前...

Global site tag (gtag.js) - Google Analytics