hdu1205 吃糖果(鸽巢定理)

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

Hint
Hint

Please use function scanf

Author
Gardon

Source
Gardon-DYGG Contest 2

与一道CF的a题是同样的idea(虽然是大水题,但还是要重视啊。这不,去年哈尔滨CCPC银牌题就有差不多的CCPC哈尔滨2019 Exchanging Gifts Gym - 102394E(数学)

CF1279 A. New Year Garland

思路:
思路,以前遇到过3个数字的形式,那时候是直接找规律得出来的。这次是n个数字,博主猜测是这个结果,但此时已经不能按照以前的思路给出证明了。

正解是鸽巢定理:n+1个物品放在n个抽屉里面,至少有一个抽屉里有两个鸽子。

本题中取出最大数mx,剩下的综合sum来做挡板,可以构成sum + 1个区域(相当于抽屉)。

如果mx ≤ sum + 1,那么就可以处理完最大数目糖果。

假设已经构成了mx个挡板处理完最大糖果,但是其他糖果还有剩余怎么办?加厚挡板!

加厚挡板:剩下的糖果种类中假设次大的数目为 m x 2 mx2 。那么此时还剩下 m x 2 1 mx2-1 个这种糖果,将其按照同样的方法全部插入在其原来所处的地方,构成一个mx2个挡板的区域。

这个挡板至少需要填充mx2 - 1个其他种类糖果。分两种情况

  1. 假设其他种类糖果填的满,那剩余的糖果继续类似的操作。
  2. 假设填不满,那剩余的 m x 2 mx2 这种糖果分配到其他挡板里面去,可供分配的位置数目为 m x 2 2 mx*2-2 。而mx2 ≤ mx,所以肯定放的够。
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long ll;
int main()
{
    int T;scanf("%d",&T);
    while(T--)
    {
        ll sum = 0,mx = 0;
        int n;scanf("%d",&n);
        for(int i = 1;i <= n;i++)
        {
            ll x;scanf("%lld",&x);
            sum += x;
            mx = max(mx,x);
        }
        sum -= mx;
        if(mx - 1 <= sum)printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

发布了697 篇原创文章 · 获赞 22 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/tomjobs/article/details/104331710