桌上有十个苹果,要把这十个苹果放到九个抽屉里,无论怎样放,我们会发现至少会有一个抽屉里面至少放两个苹果。这一现象就是我们所说的“抽屉原理”。 抽屉原理的一般含义为:“如果每个抽屉代表一个集合,每一个苹果就可以代表一个元素,假如有n+1或n+(n-1)个元素放到n个集合中去,其中必定至少有一个集合里有两个元素。” 抽屉原理有时也被称为鸽巢原理。它是组合数学中一个重要的原理。为小学六年级课程。(摘自百度百科,看到最后一句话, 我哭了、、、)
原理 && 证明 :
1. 把多于n+1个的物体放到n个抽屉里,则至少有一个抽屉里的东西不少于两件。
2. 把多于mn(m乘以n)个的物体放到n个抽屉里,则至少有一个抽屉里有不少于m+1的物体。
3. 把无穷多件物体放入n个抽屉,则至少有一个抽屉里 有无穷个物体。
4. 把(mn-1)个物体放入n个抽屉中,其中必有一个抽屉中至多有(m—1)个物体(例如,将3×5-1=14个物体放入5个抽屉中,则必定有一个抽屉中的物体数少于等于3-1=2)。
其证明均可以用反证法完成,较为简单、、、
应用 :
整除问题, 面积问题, 染色问题, 还有最简单的隔板(先这么称呼吧、)
例题 :
1. hdu 1205 吃糖果 链接:http://acm.hdu.edu.cn/showproblem.php?pid=1205
该题是一个简单的隔板问题,思路都直接复制了 ,我讲不出来 - . - #
1.把某种糖果看做隔板,如果某种糖果有n个,那么就有n+1块区域,至少需要n-1块其他种糖果才能使得所有隔板不挨在一块..也就是说能吃完这种糖果.至少需要其他种类糖果n-1块..(鸽巢原理)
2.数量最多的糖果(隔板)可以构造最多的空间,如果这种糖果有maxn个....那么需要maxn-1个其他种糖果.对于某种数量少于maxn的糖果来说,可以在原本数量最多的糖果构造的隔板上"加厚"原有的隔板...,那么这"某种糖果"就销声匿迹了.....
考虑极端情况.如果某种糖果无法在这maxn+1的空间内构造出符合条件的序列,那么这种糖果至少要有maxn+1+1个(考虑只有两种糖果的情况)...(鸽巢原理)...但是这与数量最多的那种糖果只有maxn个矛盾.....(maxn+1+1>maxn 这不等式不难理解吧....).
#include
#include
using namespace std;
#define LL __int64
int n, t;
int main()
{
while(~scanf("%d",&t))
{
while(t --)
{
LL sum = 0;
int maxn = -1;
int a;
scanf("%d",&n);
for(int i = 0; i < n; i ++)
{
scanf("%d",&a);
maxn = max(maxn, a);
sum += a;
}
if(sum - maxn + 1 >= maxn) // 本题的重点,请用心思考、、
printf("Yes\n");
else
printf("No\n");
}
}
}
2. hdu 1029 Ignatius and the Princess IV 链接:http://acm.hdu.edu.cn/showproblem.php?pid=1029
课程设计无聊到爆,就是复制粘贴呀,于是我就开始刷刷水题,因为本身的水平也就这样。
该题就是给你n 个数, 问你这n 个数中,重复次数超过(n + 1)/2 的数,很难想象这题会和这个算法联系起来,我的第一个想法就是遍历,因为他说是水题,不过两者的时间差不多,用该算法是235ms, 遍历是250ms