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 sum−mx1个挡板,执行和上面同样的方法。
- 如果挡板装的下 m x 1 mx1 mx1,剩余部分递归执行,因为每次执行,种类数目最多的糖果是会用掉的,也就是至少消耗一个种类糖果,所以不会无限递归。
- 如果装不下,那么剩余部分的数目一定小于 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;
}