HDU 1205 吃糖果 鴿巢原理 8月1

2021-07-04 06:37:04 字數 1682 閱讀 3244

吃糖果

problem description

hoho,終於從speakless手上贏走了所有的糖果,是gardon吃糖果時有個特殊的癖好,就是不喜歡將一樣的糖果放在一起吃,喜歡先吃一種,下一次吃另一種,這樣;可是gardon不知道是否存在一種吃糖果的順序使得他能把所有糖果都吃完?請你寫個程式幫忙計算一下。

input

第一行有乙個整數t,接下來t組資料,每組資料佔2行,第一行是乙個整數n(0

output

對於每組資料,輸出一行,包含乙個"yes"或者"no"。

sample input

2

34 1 1

55 4 3 2 1

sample output

no

yes hint

hint

please use function scanf

這題,自己想不到啊~~~還有這樣的原理。

思路:鴿巢原理

證明:

1.把某種糖果看做隔板,如果某種糖果有n個,那麼就有n+1塊區域,至少需要n-1塊其他種糖果才

能使得所有隔板不挨在一塊..也就是說能吃完這種糖果.至少需要其他種類糖果n-1塊..(鴿巢原理)

2.數量最多的糖果(隔板)可以構造最多的空間,如果這種糖果有maxn個....那麼需要maxn-1個其

他種糖果.對於某種數量少於maxn的糖果來說,可以在原本數量最多的糖果構造的隔板上"加厚"原

有的隔板...,那麼這"某種糖果"就銷聲匿跡了.....也就是說,對於maxn,如果剩下的sum-maxn>=maxn-1,那麼就一定能吃完。公式整理變形:sum-2*maxn-1>=0(不變形直接放上公式也可以)。

還有乙個注意點:數值sum可能超過int,所以用long long。**如下:

#includeint main()

if(sum-2*maxn+1>=0) printf("yes\n");

else printf("no\n");

}return 0;

}

還有一種思路:

如果最大堆-次大堆<=1,那麼問題肯定有解:

我們可以從最大和次大裡面每次拿乙個,然後等他們和第三大堆相等的時候

,每次從三堆裡面各拿乙個,等他們和第四大堆相等的時候

,每次從四堆裡面各拿乙個,這樣一直拿完所有堆。

問題變成了能不能使得最大堆-次大堆<=1,所以之前我們會從次大堆之外的那些堆裡面取,

來讓最大堆減少,如果能減到:最大堆-次大堆<=1,那麼原問題有解。

能否減到要看:

sum - max - max2 >= max - max2 - 1

是否成立,其中sum為總和,max為最大堆,max2為次大。

整理得:

2 * max - sum <= 1

推理完之後會發現,跟上面的公式是一回事~

hdu 1205 吃糖果(鴿巢原理)

鴿巢原理 1.把某種糖果看做隔板,如果某種糖果有n個,那麼就有n 1塊區域,至少需要n 1塊其他種糖果才能使得所有隔板不挨在一塊.也就是說能吃完這種糖果.至少需要其他種類糖果n 1塊.鴿巢原理 2.數量最多的糖果 隔板 可以構造最多的空間,如果這種糖果有maxn個.那麼需要maxn 1個其他種糖果....

hdu1205吃糖果 鴿巢原理

鴿巢原理 25只鴿子飛進了24個鴿巢,則至少有乙個鴿巢有兩個鴿子。這道題就是找出數量最大的那堆糖果,然後判斷sum max 代表總量 最大堆數量,也就是剩餘糖果的數量 是否大於 max 1,如果大於的話,代表可以吃完.因為數量為max的糖果有max 1 個空,其他種類小於max 1的糖果,可以插在m...

HDU 1205 吃糖果(鴿巢原理)

思路 1.記最多的糖果為ans,剩下糖果總數為sum 2.如果想將ans個糖果隔開,我們至少需要ans 1個其它糖果,因此sum如果小於ans 1則不行 3.如果sum大於等於ans 1,將ans個糖果隔開的區間認為是乙個空間,我們可以在放滿這ans 1個空間的基礎上,其餘每個糖果最多放在乙個空間,...