NOIP2018 D1T1 鋪設道路

2022-06-03 10:42:06 字數 1981 閱讀 9123

目錄春春是一名道路工程師,負責鋪設一條長度為 n 的道路。

鋪設道路的主要工作是填平下陷的地表。整段道路可以看作是 n 塊首尾相連的區域,一開始,第 i 塊區域下陷的深度為 di。

春春每天可以選擇一段連續區間 [l,r],填充這段區間中的每塊區域,讓其下陷深度減少 1。在選擇區間時,需要保證,區間內的每塊區域在填充前下陷深度均不為 0。

春春希望你能幫他設計一種方案,可以在最短的時間內將整段道路的下陷深度都變為 0 。

輸入

輸入檔案包含兩行,第一行包含乙個整數 n,表示道路的長度。 第二行包含 n 個整數,相鄰兩數間用乙個空格隔開,第 i 個整數為 di。

輸出

輸出檔案僅包含乙個整數,即最少需要多少天才能完成任務。

輸入樣例#1:

64 3 2 5 3 5

輸出樣例#1:

9樣例解釋1:

一種可行的最佳方案是,依次選擇: [1,6]、[1,6]、[1,2]、[1,1]、[4,6]、[4,4]、[4,4]、[6,6]、[6,6]。

資料規模與約定

對於 30% 的資料,1 ≤ n ≤ 10;

對於 70% 的資料,1 ≤ n ≤ 1000;

對於 100% 的資料,1 ≤ n ≤ 100000 , 0 ≤ di ≤ 10000。

我 抄 我 自 己?

雖然這是 noip2013 的原題「積木遊戲」……然而我並沒有做過-_-

所以考場上想了乙個比較複雜的解:

顯然觀察樣例,我們可以貪心地這樣做:對於某乙個區間,選擇最小值,將這個區間減去這個最小值,然後把區間按照這個最小值分為兩個區間分治求解。

因此,本來想寫線段樹來著……但是我及時地發現(其實是因為不想寫再多想會兒hhhh)區間的最小值是不會變化的。也就是說我們可以不去動態查詢區間最小值,而是建成笛卡爾樹,再在笛卡爾樹上進行操作。

#include#includeusing namespace std;

typedef long long ll;

const int maxn = 100000;

const int maxd = 10000;

struct nodetree[maxn + 5], *tcnt, *nil, *root;

void init()

node *newnode(int d)

stackstk;

int d[maxn + 5];

void dfs(node *rt, int x)

int main()

if( !stk.empty() ) stk.top()->ch[1] = nw;

nw->ch[0] = lst;

stk.push(nw);

}while( !stk.empty() )

dfs(root, 0);

printf("%lld\n", root->ans);

return 0;

}

我們實際上是求如圖的塊的個數。

我們不妨在塊的右端點去統計每一塊對答案的貢獻。

所以就很簡單了:

(1)如果 d[i] >= d[i+1],則 ans+=(d[i]-d[i+1])

(2)如果 d[i] < d[i+1],則 continue

最後 ans+= d[n] 即可

#includetypedef long long ll;

const int maxn = 100000;

int d[maxn + 5];

int main()

NOIP2018 T1 鋪設道路

題目描述 春春是一名道路工程師,負責鋪設一條長度為 nn 的道路。鋪設道路的主要工作是填平下陷的地表。整段道路可以看作是 nn 塊首尾相連的區域,一開始,第 ii 塊區域下陷的深度為 d idi 春春每天可以選擇一段連續區間 l,r l,r 填充這段區間中的每塊區域,讓其下陷深度減少 11。在選擇區...

NOIP2018提高組D1T1 鋪設道路

題目描述 春春是一名道路工程師,負責鋪設一條長度為 n 的道路。鋪設道路的主要工作是填平下陷的地表。整段道路可以看作是 n 塊首尾相連的區域,一開始,第 i 塊區域下陷的深度為 d i 春春每天可以選擇一段連續區間 l,r 填充這段區間中的每塊區域,讓其下陷深度減少1。在選擇區間時,需要保證,區間內...

NOIP2018Day1T1 鋪設道路

春春是一名道路工程師,負責鋪設一條長度為 n 的道路。鋪設道路的主要工作是填平下陷的地表。整段道路可以看作是 n 塊首尾相連的區域,一開始,第 i 塊區域下陷的深度為 d i 春春每天可以選擇一段連續區間 l,r 填充這段區間中的每塊區域,讓其下陷深度減少 1 在選擇區間時,需要保證,區間內的每塊區...