当青训营遇上码上掘金 题目:
- 现有 n 个宽度为 1 的柱子,给出 n 个非负整数依次表示柱子的高度,排列后如下图所示,此时均匀从上空向下撒青豆,计算按此排列的柱子能接住多少青豆。(不考虑边角堆积)
这题之前在本人在leetcode上做过一次 接雨水 然后就处理下输入就可以了
首先是动态规划 其实本质的思想就是一个分类 这题可以分为两类以最高点为分界线 从左向右至最高点为一类,从右向左到最高点为一类每一次只需要获取当前值由哪一种状态转过来,例如left【i】是从left【i-1】上一次 跟save【i】当前值 取一个更大的值 因为只有更大的值才能获取到当前点的最高水位 当第二次遍历的时候 从右边向左边遍历因为每次也是取得 最大值 所以最后每一个点会有一个相互的差值 这个差值即为你当前这个能够承载的 青豆数量 也是雨水数量 因为你是从上一个最高的状态转移过来的 左边右边同时取最高点的更小的一个 所以当前能够承载的数量为最后的ans 可以根据下面代码来看,值得注意的还是边界问题
//左边取完 右边再取 最后取重复的即可
#include<iostream>
#include<cstdio>
using namespace std;
const int N = 100;
int save[N],left[N],right[N];
int main() {
scanf("height = [%d,%d,%d,%d,%d,%d,%d,%d,%d]",&save[1],&save[2],&save[3],&save[4],&save[5],&save[6],&save[7],&save[8],&save[9]);
int n = 9;
for(int i = 1;i <=9;i++)
{
left[i] = max(left[i-1],save[i]);
}
for(int i = 9;i >=1;i--)
{
right[i] = max(right[i+1],save[i]);
}
int ans = 0;
for(int i = 1;i <=9;i++)
{
ans += min(left[i],right[i])-save[i];
}
cout <<ans << endl;
return 0;
}