1. 程式人生 > >HDU 1205 吃糖果(鴿籠原理)

HDU 1205 吃糖果(鴿籠原理)

鴿籠原理(也稱抽屜原理)         簡單的表述如下,這個原理看起來非常通俗,好像是在說一句廢話一樣,然而數學就是這樣,總是需要證明一下。

        證明是用反證法:假設每個籠子只有一個鴿子,那麼必定有一個鴿子不在籠子裡,和原命題衝突。   

        另外還有一個拉姆齊定理,英文是Ramsey定理,是鴿籠原理的擴充套件,鑑於拉姆齊定理比較難懂,就不深入講解了,Ramsey定理的證明是數學界裡難度非常高的證明題。

若有n個籠子和n+1只鴿子,所有的鴿子都被關在鴿籠裡,那麼至少有一個籠子有至少2只鴿子。

題目:

Problem Description

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

Input

第一行有一個整數T,接下來T組資料,每組資料佔2行,第一行是一個整數N(0<N<=1000000),第二行是N個數,表示N種糖果的數目Mi(0<Mi<=1000000)。

Output

對於每組資料,輸出一行,包含一個"Yes"或者"No"。

Sample Input

2

3

4 1 1

5

5 4 3 2 1

Sample Output

No

Yes

先思考1分鐘

......

解題思路:

1、由於Gardon吃糖需要先吃一顆型別為X的,再吃一顆型別為Y的,對於任意型別的糖果,需要能夠用其他糖果隔開。

2、把某種糖果看做隔板,如果某種糖果有n個,那麼就有n塊區域,至少需要n-1塊其他種糖果才能使得所有隔板不挨在一塊,也就是說能吃完這種糖果.至少需要其他種類糖果n-1塊。(鴿巢原理)

3、這裡面只要考慮到,對於數量最多的糖果來說,需要有一定數量的其他糖果來隔開。

#include<stdio.h>
#include<stdint.h>

int main()
{
    //輸入次數
    int count;

    scanf("%d", &count);

    while (count--)
    {
        //糖果中數量的最大值
        int max_value = -1;
        //糖果種類數量
        int sugar_type_count;
        //糖果總數
        int64_t sum = 0;

        scanf("%d", &sugar_type_count);

        for (int i = 0; i < sugar_type_count; i++)
        {
            int suger_count;

            scanf("%d", &suger_count);

            sum += suger_count;
            //更新最大值
            if (max_value < suger_count)
                max_value = suger_count;
        }

        //剩餘糖果大於等最大值-1
        //如11顆糖,其中一種有6顆,別的顏色有5顆,正好可以隔開這6顆糖
        if ((sum - max_value + 1) >= max_value)
            printf("Yes\n");
        else
            printf("No\n");
    }

    return 0;
}