1. 程式人生 > >Noip 2013 Day2 T1 積木大賽(block)

Noip 2013 Day2 T1 積木大賽(block)

ace int 所有 沒有 lock 補充 efi cnblogs names

Noip 2013 Day2 T1 積木大賽(block)

【題目描述】

春春幼兒園舉辦了一年一度的“積木大賽”。今年比賽的內容是搭建一座寬度為的大廈,大廈可以看成由塊寬度為1的積木組成,第??塊積木的最終高度需要是??? 。

在搭建開始之前,沒有任何積木(可以看成塊高度為 0 的積木)。接下來每次操作,小朋友們可以選擇一段連續區間[, ??],然後將第塊到第??塊之間(含第 L 塊和第 R 塊)所有積木的高度分別增加1。

小M是個聰明的小朋友,她很快想出了建造大廈的最佳策略,使得建造所需的操作次數最少。但她不是一個勤於動手的孩子,所以想請你幫忙實現這個策略,並求出最少的操作次數。

【輸入】

輸入文件為 block.in

輸入包含兩行,第一行包含一個整數,表示大廈的寬度。

第二行包含個整數,第??個整數為?

?? 。

【輸出】

輸出文件為 block.out

僅一行,即建造所需的最少操作數。

這道題並沒有什麽難度,只是我以為很難,題目中提到區間內增加一個值,我很自然的想到了什麽線段樹啊,樹狀數組,離線前綴和啊。果然,我又想多了。還好自己反應過來了。正解的話貪心就好了。

我們假設每一次搭建操作都是一條刪除線,那麽答案就是最少的刪除線條數。

當hi<hi+1時,顯然必須增加刪除線,去補充多出來的hi+1−hi部分;

當hi>hi+1時,有些刪除線就必須要終止,接下來只有hi+1條刪除線可以存在。

於是只需要計算增加的刪除線總數即可,時間復雜度為O(n)。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cmath>
 5 #include <cstring>
 6 #define INT_MAX_ 0x7fffffff
 7 #define LONG_MAX_ 0x7fffffffffffffffll
 8 #define pi acos(-1)
 9 #define N 100010
10 #define
M 1010 11 using namespace std; 12 13 inline int read() 14 { 15 int data=0,w=1; 16 char ch=0; 17 while(ch!=- && (ch<0 || ch>9)) ch=getchar(); 18 if(ch==-) w=-1,ch=getchar(); 19 while(ch>=0 && ch<=9) data=data*10+ch-0,ch=getchar(); 20 return data*w; 21 } 22 23 inline void write(int x) 24 { 25 if(x<0) putchar(-),x=-x; 26 if(x>9) write(x/10); 27 putchar(x%10+0); 28 } 29 30 int n; 31 int pre_house,all_of_house,nowVal; 32 33 int main() 34 { 35 freopen("block.in","r",stdin); 36 freopen("block.out","w",stdout); 37 38 n = read(); 39 for(int i = 1; i <= n; i++) 40 { 41 nowVal = read(); 42 if(pre_house < nowVal) all_of_house += nowVal - pre_house; 43 pre_house = nowVal; 44 } 45 write(all_of_house); 46 47 return 0; 48 }

Noip 2013 Day2 T1 積木大賽(block)