為了增加顧客,sally的店鋪決定提供免費午餐,頓時門庭若市,但是不久sally的原材料不足了….因此sally決定公布一項決定:凡是來本店吃免費午餐的,一天吃能吃一次,吃的數量必須比上一次吃的少, 點的必須在上一次後面,且免費午餐將只有n個種類任君選擇,為了能吃到最多的免費午餐,你將如何安排每日吃的數量呢?
第一行乙個數n,表示免費午餐的種類(0<=n<=100000)
第二行n個數,表示每個免費午餐的數量(0<=數量<=100000)
很容易可以看出,這是個最長下降子串行。(我都看出來了)
剛開始想的是n^2暴力
i=1——n
j=1——i-1
f[i]=max
然而看了看資料,嗯,好像會爆的樣子。
想不到優化的方法,嗯,先不管了,把前兩道水題刷完再說。刷完,再看題,嗯,一臉懵逼
直到姜老師問我以前學的二分+最長不下降子串行還記不記得,才想起可以用二分(當時沒想起來做法)。然後我看姜老師很生氣的樣子,在最後20分鐘決定自己試一試。我嘗試把a[i]排序並記錄序號b[i],每次都二分在a中找出剛好比它大的從這個倒著迴圈到最大的,更新f[i]。然而沒調完就提交了,而且有乙個細節沒有考慮到,仍然爆時間。
看了題解,只有乙個標丟在上面,給的**過期了,只提到了「不過這道題有個陷阱,就是如果數量為0,那麼意思就是根本吃不了,換句話說就是0不能算是子串行」,還是有點用的。標沒看懂,然後聽了一波講題,然後和標一結合,好像有點明白。然後翻很久以前的題解,翻出自己的標,終於懂了!這個故事告訴我們,學過的題千萬不能忘,就算忘了也要保留題(標)解(程)。
好了,現在才是題解。
我們考慮用f[j]儲存長度為j的從起點到當前位置的最長下降子串行,每加入乙個點,如比最後乙個點小則加入序列;否則在f中二分查詢乙個位置,要求當前點比該位置打,並小於該位置的前乙個,更新該位置的值,繼續下乙個點。
時間複雜度o(n log n)
var
n,i,j,k,ans,l,r,mid:longint;
f:array[0..100050]of longint;
function
max(a,b:longint):longint;
begin
if a>b then
exit(a)
else
exit(b);
end;
begin
readln(n);
f[0]:=maxlongint;
for i:=1
to n do
begin
read(k);
if k=0
then
continue;
if kthen
begin inc(j);f[j]:=k;continue;end;
l:=1;r:=j;
while l<=r do
begin
mid:=(l+r) div
2; if (k1])and(k>f[mid]) then
begin
f[mid]:=k;break;
end;
if k>f[mid] then r:=mid-1
else l:=mid+1;
end;
end;
writeln(j);
end.
天下沒有免費的午餐
從前,有一位愛民如子的國王,在他的英明領導下,人民豐衣足食,安居樂業。深謀遠慮的國王卻擔心當他死後,人民是不是也能過著幸福的日子,於是他招集了國內的有識之士。命令他們找乙個能確保人民生活幸福的永世法則。三個月後,這班學者把三本六寸厚的帛書呈上給國王說 國王陛下,天下的知識都匯集在這三本書內。只要人民...
邊遠山區的免費午餐
中星九號公升空了,給西部偏遠地區的電視受眾送去了更多的實惠。在中星九號公升空後,西部邊遠地區的一些電視使用者吃驚地現,過去沒見過的幾十套頻道節目突然出現了。其實這不值得奇怪,因為中星九號是中國首個直播衛星,於6月9日20時15分在西昌衛星發射中心成功發射,按照要求將給西部邊遠地區免費傳輸47套免費的...
免費也好吃的軟體午餐
強悍的免費分割槽工具 軟體名稱 partition logic 軟體版本 0.55 授權方式 免費軟體 軟體大小 384kb 軟盤映象 1.8mb 光碟映象 軟盤映象 http visopsys.org files partlogic partlogic 0.55 iso.zip 光碟映象 還記得著...