如果手动去搭积木大家都会,但是怎样描述这种规则呢?
一开始想递归,用线段树优化(自底向上)。或者用大根堆维护高度相同的连续区间,每个区间记录左边和右边的区间,每次合并最高的那个和它左右中较高的一边(自顶向下)。
都是可行的。但是,和《花匠》一题的情形相似,学长传下来的《混分导论》上的程序怎么这么短?!
有没有O(n)做法?换了种思路。从左到右考虑这一列积木。如果左边的比这个高,那么搭左边的时候顺带搭上它即可;如果左边的比这个矮,在左边的基础上升高一截即可。
#include <cstdio>
using namespace std;
int main()
{
int n, a, b;
scanf("%d %d", &n, &a);
int ans = a;
while (--n) {
scanf("%d", &b);
if (b > a)
ans += b-a;
a = b;
}
printf("%d\n", ans);
return 0;
}
序列上的问题,可以整体看、分段看、从左向右看,以寻找联系。