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 1 mx1 mx1,次大数目为 m x 2 mx2 mx2,总数为 s u m sum sum,那么可以构成 s u m − m x 1 sum-mx1 summx1个挡板,执行和上面同样的方法。

  1. 如果挡板装的下 m x 1 mx1 mx1,剩余部分递归执行,因为每次执行,种类数目最多的糖果是会用掉的,也就是至少消耗一个种类糖果,所以不会无限递归。
  2. 如果装不下,那么剩余部分的数目一定小于 m x 1 mx1 mx1,也就可以插入到原挡板中。
#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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值