題解 APIO2007 風鈴

2022-05-01 21:03:09 字數 1600 閱讀 9361

你需要選乙個滿足下面兩個條件的風鈴:

(1) 所有的玩具都在同一層(也就是說,每個玩具到天花板之間的杆的個數是一樣的)或至多相差一層。

(2) 對於兩個相差一層的玩具,左邊的玩具比右邊的玩具要更靠下一點。

風鈴可以按照下面的規則重新排列:任選一根杆,將杆兩頭的線「交換」。也就是解開一根杆左右兩頭的線,然後將它們綁到杆的另一頭。這個操作不會改變更下面的杆上線的排列順序。

其實看著這個題目我第一反應是平衡樹,像splay,fhq之類的可以完成的區間翻轉操作,但是這個題目不同的是,他改變兩個之後其內部的順序不變,所以我們可以感性的分析出來反轉的順序對答案沒有太多的影響

分析:

由於最大最小相差深度小於等於1,所以可以先dfs一遍,特判一下,0輸出0,大於1就是-1(考試時候忘了特判就掛了),對於等於1情況,我們來分析一下什麼時候需要翻**

- 左小右大

- 左有小有大,右大

- 左小,右有小有大

所以,對於這個需要再來一次dfs,用0表示小,1表示大,2表示有小有大,遇到上面三種情況就ans++

完整**如下:

#include #include 

#include

#include

#include

using

namespace

std;

#define re register

#define gc getchar()

#define ll long long

#define il inline

const

int n= 100010

;il

intread()

while(ch>='

0'&&ch<='9'

)

return x*f;

}int ls[n],rs[n],_max=-1,_min=1e8,deep[n],n,ans,flag=1

;void dfs1(int

u)

else

if(rs[u])

else

}namespace

sp1 ;

int dfs(int u,int

dep)

int a=dfs(ls[u],dep+1

);

int b=dfs(rs[u],dep+1

);

if(a==0&&b==1) ++ans;

if(a==2&&b==1) ++ans;

if(a==0&&b==2) ++ans;

if(a==2&&b==2) flag=0

;

return

x[a][b];

}intmain()

cout

}};int

main()

if(_max==_min) cout<<0

; cout

<<-1

;

return0;

}

很多大佬莫名mle了,但是這個的空間是足夠的,只用了16m

題解 APIO2007 動物園

傳送門 對於這個題目很明顯的就是狀壓dp,不過,作為乙個不會狀壓dp的蒟蒻,考場讓只能根據大佬們的之前聊天和對狀壓dp的印象來瞎搞 狀態是這樣設計的 f i,j 表示轉移到從第i個位置出發的j表示五個的動物的狀態能使多少個小朋友滿意 s i,j 表示從i出發的5個位置中表示j的狀態使多少個小朋友滿意...

題解 APIO2007動物園

首先一眼感受到這題特別的性質 5個?這麼小的,感覺就像是狀壓。腦補了一下,如果沒有環的話應該很好做吧 有環怎麼辦?5真的很小的,隨便亂搞肯定也可以。那就放在外面暴力列舉吧。然後正解就出來了。然而這題題面真的有毒吧。說好的不能全部選走?我還多加了乙個維度,結果資料裡面允許全部取走 然後對於 5的點單獨...

APIO2007 動物園 題解

x 原題鏈結 有一圈圍欄,每個圍欄有一種動物,有若干個小朋友,每個小朋友能看到連續的 5 個動物,每個小朋友對每種的動物的喜好不一樣,如果乙個小朋友會高興,當且僅當至少有乙個他害怕的動物被移走,或者是至少有乙個他喜歡的動物沒有被移走。問調整某些動物後,最多有多少個小朋友會高興。題目的目的是移走若干動...