观察下面的数字三角形。
在每一个点,只能走到左下角的一个点,或者右下角的一个点。
特别的,三角形中值为-1的点是不可经过的,请不要经过这些点。
找到一条从最高点到最低点的路径,使得经过的数字的和最大,输出这个和,如果没有这样的路径,输出”Impossible”(输出不要加双引号)。
7
3 8
8 1 0
2 7 4 4
4 -1 2 6 5
解题思路:第一思路就是暴力法,通过遍历三角形的所有路线,对比最终的值就能得出结果。但是效率不高,原因是三角形每多一层,遍历量则乘以2,这样复杂度是O(2^n),如果是多组数据的话必然会LTE,所以需要使用一种新的方法来改进效率。
这种方法叫做动态规划。在数字三角形的每一个节点都有两个策略,要不是向左走,要不是向右走,一直到最后一步。不妨定义题目给出的数字三角形是a(i,j),另一个数字三角形d(i,j),其中i与j表示第i层的第j个元素。
对于任意一个d(i,j),它表示当前状态下走到a(i,j)节点所有路线中的最大值,也就是说d事实上是一种状态。对于d的计算,给出下列方法:
状态转移方程:
这样,d(n,j)(也就是数字三角形的最后一层)将会得到j个可能的最大值,将这些值求出最大值即可。
重点来了,如何处理-1这个节点?题目要求是遇到-1表示不能通过,其实可以通过标记元素来避免这个问题。当a(i,j)是-1的时候,将d(i,j)对应的赋值为0,这样该状态不会被下一个状态累加。
代码细节:
1.解题思路里面提到了当a(i,j)是-1的时候,将d(i,j)对应的赋值为0,这样会不会对下一个状态有影响?事实上是不会的。原因是题目给出的数字全部是非负数,这意味着数字三角形每过一层都会数值增加,如果将状态清零,这样子该状态到最后一层肯定不是最大值。
2.注意题目还有一个要求是无法输出结果的情况,这种情况是当三角形里面某一层全部是-1的时候就无法输出结果。
3.定义二维数组的下标是从(1,1)开始的,所以不需要考虑越界的问题。前提是初始化二维数组为0。
代码清单:
<script src="https://code.csdn.net/snippets/542218.js"></script>