jzoj P1331 超級教主

2021-08-15 09:11:47 字數 1467 閱讀 8262

lhx教主很能跳,跳需要消耗能量,每跳1公尺就會消耗1點能量。

教主為了收集能量,來到了乙個神秘的地方,教主的正上方每100公尺處就有乙個能量球(也就是這些能量球位於海拔100,200,300……公尺處),每個能量球所能提供的能量是不同的,一共有n個能量球(也就是最後乙個能量球在n×100公尺處)。教主為了想收集能量,想跳著吃完所有的能量球。教主可以自由控制他每次跳的高度,接著他跳起把這個高度以下的能量球都吃了,他便能獲得能量球內的能量,接著吃到的能量球消失。教主不會輕功,教主不會二段跳,所以教主不能因新吃到的能量而變化此次跳躍的高度。並且教主還是生活在地球上的,所以教主每次跳完都會掉下來。

問教主若要吃完所有的能量球,最多還能保留多少能量。

對於10%的資料,有n≤10;

對於20%的資料,有n≤100;

對於40%的資料,有n≤1000;

對於70%的資料,有n≤100000;

對於100%的資料,有n≤2000000。

保證對於所有資料,教主都能吃到所有的能量球,並且能量球包含的能量之和不超過2^31-1。

這題我們設f[i]表示跳完了前i所保留的最大能量

不難推出轉移:

f[i]=max

沒錯時間複雜度是o(n^2)的!

所以肯定會tle

我們要優化,因為轉移時候,我們只需要找到f[j]-sum[j]的最大值轉移過來就可以了,所以用單調佇列

維護一下就可以了

時間複雜度:o(n)

var

cmax,sum,f:array [0..2000001] of longint;

head,tail,i,j,k,n,m,x:longint;

function

max(aa,bb:longint):longint;

begin

if aa>bb then

exit(aa);

exit(bb);

end;

begin

readln(n,f[0]);

cmax[1]:=0;

head:=1;

tail:=1;

for i:=1

to n do

begin

read(x);

sum[i]:=sum[i-1]+x;

while (head<=tail) and (f[cmax[head]]100) do inc(head);

f[i]:=f[cmax[head]]+sum[i]-sum[cmax[head]]-i*100;

k:=f[i]-sum[i];

while (head<=tail) and (f[cmax[tail]]-sum[cmax[tail]]<=k) do dec(tail);

inc(tail);

cmax[tail]:=i;

end;

writeln(f[n]);

end.

13 3 巢狀迴圈

迴圈語句可以在迴圈內使用任意型別的命令,包括其他迴圈命令。這種迴圈叫做巢狀迴圈 nested loop 在使用巢狀迴圈時,你是在迭代中使用迭代,與命令執行的次數是乘積關係。chendajie chendajie nest loop cat test1 bin bash nesting for loo...

1 3 3 啟用函式介紹

到目前為止,我們使用的啟用函式全部都是 函式,然而這並不一定是最好的函式,有時其他可選的函式效果也很好,下面我們來介紹一下其他的函式。如圖所示,我們在這裡使用 函式作為啟用函式。我們現在使用g z x 作為更一般的可以使用的函式。我們這裡介紹一下tanhx,是雙曲正切函式。tanhx,實際上在數學上...

LintCode 133 最長單詞

給乙個詞典,找出其中所有最長的單詞。您在真實的面試中是否遇到過這個題?yes 樣例在詞典中,最長的單詞集合為 internationalization 在詞典中,最長的單詞集合為 like love hate 挑戰 遍歷兩次的辦法很容易想到,如果只遍歷一次你有沒有什麼好辦法?class soluti...