当青训营遇上码上掘金
问题描述
有n个宽度1的柱子给定n个非负整数依次表示柱子的高度,当青豆的高度超过旁边的柱子高度时会发生溢出,求在上述条件的约束下能攒下多少青豆,1乘1的格子代表一个单位的青豆,求能攒下多少个单位的青豆
动态规划
要想了解攒青豆这个算法我们有必要去了解一下什么叫做动态规划。动态规划的精髓在于动态两个字,即它的每一个决策都会依赖于当前的阶段,又会引起下一个阶段的状态变化,一个决策序列在变化的状态中产生,得到这种多阶段变化的最优解的过程就叫做动态规划。它的基本思路和分治算法类似,也是将待求的问题分成若干个子问题,按顺序求解子问题和前一问题的解,并且为后一子问题的求解提供有用的信息,在求子问题时列出可能的局部解,通过决策去求得子问题的最优局部解
攒青豆算法
使用两个数组rightMax和leftMax用于分别储存某一个柱子右边的柱子高度最大值和左边柱子高度的最大值。这里就是用到了动态规划的思想,我们用height数组去存储柱子高度那么我们可以通过遍历得到前面我们所设定的两个数组的值代码如下
` leftMax[0] = height[0];
for (int i = 1; i < size; ++i) {
leftMax[i] = max(leftMax[i - 1], height[i]);
}
rightMax[size - 1] = height[size - 1];
for (int i = size - 2; i >= 0; --i) {
rightMax[i] = max(rightMax[i + 1], height[i]);
}`
得到这两个数组之后我们就得到了任意一个柱子左边的最大值和右边的最大值,然后我们就可以得到第i根柱子上的青豆高度
` min(leftMax[i], rightMax[i]) - height[i];`
将数组遍历累加就得到了青豆数量。这里主要是用了动态规划的思想将每一根柱子都当做一个子问题去解决,但是并不是完全完整的动态规划。