# NOIP2018_Day1T1_铺设道路
题意:
春春是一名道路工程师,负责铺设一条长度为 \(n\) 的道路。
铺设道路的主要工作是填平下陷的地表。整段道路可以看作是 \(n\) 块首尾相连的区域,一开始,第 \(i\) 块区域下陷的深度为 \(d_{i}\)
春春每天可以选择一段连续区间 \([L,R]\) ,填充这段区间中的每块区域,让其下陷深度减少 \(1\)。在选择区间时,需要保证,区间内的每块区域在填充前下陷深度均不为 \(0\) 。
春春希望你能帮他设计一种方案,可以在最短的时间内将整段道路的下陷深度都变为 \(0\)。
解:
贪心即可,援引【我醉了】大佬题解中的话:
用 \(f[i]\) 表示前i个坑所铺设的最少天数,那么要做的只需比较一下当前的 \(a[i]\) (就是坑的深度)和 \(a[i-1]\) ,分两种情况:
如果 \(a[i]<=a[i-1]\) ,那么在填 \(a[i-1]\) 时就可以顺便把 \(a[i]\) 填上,这样显然更优,所以 \(f[i]=f[i-1]\);
否则的话,那么在填 \(a[i-1]\) 时肯定要尽量把 \(a[i]\) 一块填上, \(a[i]\) 剩余的就单独填。所以, \(f[i]=f[i-1]+(a[i]-a[i-1])\)。
代码:
#include <bits/stdc++.h>
using namespace std;
int n;
int f[100010], a[100010];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i <= n; i++)
if (a[i] > a[i - 1])
f[i] = f[i - 1] + (a[i] - a[i - 1]);
else f[i] = f[i - 1];
printf("%d\n", f[n]);
return 0;
}