# NOIP2018_Day1T1_鋪設道路
阿新 • • 發佈:2020-08-01
題意:
春春是一名道路工程師,負責鋪設一條長度為 \(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; }