把每天的区间填平操作看成给相邻深度差分,答案为相邻深度差的正部之和 max(d_i - d_{i-1}, 0)。
OJ: roj
题目 ID: 3658
难度:普及
标签:贪心差分
创建: 2026-10-02 13:43
更新: 2026-10-06 16:14
题目描述
道路长度为 n=6,d=[4,3,2,5,3,5];样例输出:9。数据范围:
思路
把每次操作看成砖块图(位置为列、高度为
参考代码
Python 版:
python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-10-02 13:43
# update_at: 2026-10-02 13:43
import sys
from itertools import pairwise
def solve() -> None:
data = iter(map(int, sys.stdin.buffer.read().split()))
n = next(data)
depth = [next(data) for _ in range(n)]
# 每天只能在"深度非零"的连续段内整体 -1,把每个位置填到 0 的次数里
# 与左邻共用的部分不会重复计数;答案 = 相邻差分的正部之和。
ans = sum(max(cur - prev, 0) for prev, cur in pairwise([0] + depth))
print(ans)
if __name__ == "__main__":
solve()C++ 版(同一算法):
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-06 16:14
* update_at: 2026-10-06 16:14
*/
#include <cstdio>
typedef long long ll;
const int MAXN = 1e5 + 5;
int n;
ll d[MAXN]; // d[i] 表示第 i 天的道路深度
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
scanf("%lld", &d[i]);
// 每次操作填平一个区间,把"竖直视角"看成铺横条:
// 只有比左邻高出来的层必须以 i 为左端点新开一次操作,
// 答案 = sum(max(d[i] - d[i-1], 0)),约定 d[0] = 0。
ll ans = 0;
for (int i = 1; i <= n; ++i)
if (d[i] > d[i - 1])
ans += d[i] - d[i - 1];
printf("%lld\n", ans);
return 0;
}