BZOJ2240 積木遊戲

2021-08-04 06:21:57 字數 1375 閱讀 4323

題目描述

……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邊 如下圖所示 遊...