1. 程式人生 > 實用技巧 ># NOIP2018_Day1T1_鋪設道路

# 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;
}