題目描述……n)
。那麼如果存在乙個整數k
[2,n-1],
使得對所有的位置i
,下式都成立,則稱h
是一座山峰。
h[i]>h[i-1],1
h[i]>h[i+1],k
現在你有乙個超級工具,每次操作可以給一段連續的區間各位置都疊放上一塊積木,使得高度同時增加1個單位,現在有乙個「高木」排列,需要將其改造為一座山峰,只允許使用這種超級工具,最少需要操作幾次可以達到這個目標呢?假設積木無限**。
輸入輸入檔案只有一組資料。
第一行包含乙個整數n,為上文提到的初始排列中「高木」的個數。
第二行包含n個正整數,表示由左到右的n個位置「高木」的初始高度h[i],
數字由空格隔開。
輸出輸出包含乙個整數,表示所需要的最少的操作次數。
樣例輸入
63 4 3 6 7 8
樣例輸出2
提示對於30%的資料,滿足n<=20,h[i]<=50.
對於50%的資料,滿足n<=100,h[i]<=1000
對於全部的資料,滿足3<=n<=105,h[i]<=107
題解:貪心。沒錯,是貪心,不是dp。
先考慮乙個更簡單的問題,如果我們的目標排列是嚴格遞增,需要多少次操作?
考慮到操作的這樣幾個性質:
第一:操作是無序的。
第二:操作的區間可以由
i~j擴充到
i~n,
而並不影響最優解。
對於第 i
根高木,如果其高度
h[i]<=h[i-1]
,則需要對
i~n進行
h[i-1]-h[i]+1
次操作;否則就不需要。
最優解為每根高木所需要的操作次數之和,用
ans表示。
現在回到原問題。
原問題可以看做是兩個嚴格上公升序列的組合。
所以,最終最優解為兩個上公升序列所需操作的最大值,即ans=max(ans1,ans2)
#include#include#include#include#include#includeusing namespace std;
const int n=1e5+10;
long long n, h[n], ans[2][n], sum;
int main()
sum=ans[0][n];
for( int i=n-1; i; i-- )
printf( "%lld\n", sum );
return 0;
}
Noip2013 積木遊戲
描述 春春幼兒園舉辦了一年一度的 積木大賽 今年比賽的內容是搭建一座寬度為 n 的大廈,大廈可以看成由 n 塊寬度為1的積木組成,第 塊積木的最終高度需要是hi。在搭建開始之前,沒有任何積木 可以看成 n 塊高度為 0 的積木 接下來每次操作,小朋友們可以選擇一段連續區間 l,r 然後將第 l 塊到...
NOI1029 積木遊戲(dp)
include include using namespace std define max a,b ab swap a,b 將a,b,c排序 if b c swap b,c if a b swap a,b 排序後儲存時,p i j a的值始終小於p i j b的值,這樣可以使判斷是否包含時更方便 ...
NOI1997 積木遊戲 dp
輸入檔案 buildinggame.in輸出檔案 buildinggame.out簡單對比 時間限制 1 s 記憶體限制 128 mb sercoi 最近設計了一種積木遊戲。每個遊戲者有n塊編號依次為1 2,n的長方體積木。對於每塊積木,它的三條不同的邊分別稱為 a邊 b邊 和 c邊 如下圖所示 遊...