题目描述
正处在某一特定时期之中的李大水牛由于消化系统比较发达,最近一直处在饥饿的状态中。某曰.上课,正当他饿得头昏眼花之时,眼前突然闪现出了一个n* m(n and m < = 200)的矩型的巨型大餐桌,而自己正处在这个大餐桌的一-侧的中点下边。餐桌被划分为了n*m个小方格,每一个方格中都有一个圆形的巨型大餐盘,上面盛满了令李大水牛朝思暮想的食物。李大水牛已将餐桌上所有的食物按其所能提供的能量打了分(有些是负的,因为吃了要拉肚子),他决定从自己所处的位置吃到餐桌的另一侧,但他吃东西有一个习惯一只吃自 己前方或左前方或右前方的盘中的食物。
由于李大水牛已饿得不想动脑了,而他又想获得最大的能量,因此,他将这个问题交给了你。
每组数据的出发点都是最后一行的中间位置的下方!
输入
第一行为m n.(n为奇数),李大水牛- -开始在最后一行的中间的下方接下来为m* n的数字距阵.
共有m行,每行n个数字数字间用空格隔开.代表该格子上的盘中的食物所能提供的能量.数字全是整数.
输出
一个数,为你所找出的最大能量值
题目分析
此题给出了mXn矩阵, 矩阵元素的值有正有负, 由于只能向前前进, 不能水平向左/右前行,
所以此题抽象出来就是从最下层出发, 每一层只能从正上方/左上方/右上方取一个元素, 使得所取元素和最大
下面说到矩阵的长度, 我使用length来代替, 宽度用width
假如我们用一个dp数组来存储吃掉某个元素后能获得的最大能量
故我们开一个大小为width的dp数组
dp[i]表示吃i后, 能获得的最大总能量值
下面我用 [s,e]表示起始点的x的范围为s, s+1, s+2…e-1, e
举例
假设m = 11, n = 7
第一次吃, 必须从中点出发, (0 + 10) / 2 = 5. 所以从5开始出发
那么第一次吃可能的选择如图浅绿色表示(起始点-----[5, 5])
因为上一次吃, 可以吃到b, a, c中的一个, 而他们的x坐标的范围是[4, 6], 所以第二次吃可能的选择如图深绿色表示(起始点-----[4, 6]),
同理可得第三次吃可能的选择如图橘色表示(起始点-----[3, 7])
.
.
.
随着我们一次次往后面吃, 可供选择的范围越来越大了, 而我只想要有最优解, 也就是元素和最大的那一个, 该怎么办呢? 一般来说, 用动态规划解题, 我么想要求得什么结果, 在dp里最好就存储什么.
分析
i 表示上一次所在的层数, j 表示列数
1.对可供选择的出发点的边界进行分析, 如左边界
- 向左前方行进(当j > 0 时, 才可以向左前方吃)
如果从左边界向左前方行进, (第一次b, 第二次d, 第三次m)
其转移方程为 dp[i][j - 1] = dp[i - 1][j] + energy[i][j - 1] (j > 0 && j == s )
此方程对右边界也成立
再拿上图分析
dp[5][3] = dp[6][4] + energy[5][3];
dp[4][2] = dp[5][3] + energy[4][2];
…
- 向正前方行进
还是拿左边界举例
第一次a, 第二次(e,g), 第三次(n,r)…
(左边界)状态转移方程为:
dp[i][j] = max(dp[i][j], dp[i][j + 1]) + energy[i][j]------(s < e)
dp[i][j] = max(dp[i][j]) + energy[i][j]---------------------(s == e)
(右边界)状态转移方程为:
dp[i][j] = max(dp[i][j - 1], dp[i][j]) + energy[i][j]------(s < e)
dp[i][j] = max(dp[i][j]) + energy[i][j]---------------------(s == e)
再次进行分析