你需要選乙個滿足下面兩個條件的風鈴:分析:(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 個動物,每個小朋友對每種的動物的喜好不一樣,如果乙個小朋友會高興,當且僅當至少有乙個他害怕的動物被移走,或者是至少有乙個他喜歡的動物沒有被移走。問調整某些動物後,最多有多少個小朋友會高興。題目的目的是移走若干動...