骚操作之鸽巢原理

桌上有十个苹果,要把这十个苹果放到九个抽屉里,无论怎样放,我们会发现至少会有一个抽屉里面至少放两个苹果。这一现象就是我们所说的“抽屉原理”。 抽屉原理的一般含义为:“如果每个抽屉代表一个集合,每一个苹果就可以代表一个元素,假如有n+1个元素放到n个集合中去,其中必定有一个集合里至少有两个元素。” 抽屉原理有时也被称为鸽巢原理。它是组合数学中一个重要的原理。

在acm中也是会遇到的,比如两个人对打的得分问题

110个人参加一个国际象棋单循环比赛,每两人都进行一局比赛,胜积1分,败积-1分,平积0分。结果又32个平局。证明:必有两个人积分相同。

2给两个序列A,B |A|=N且元素为1-M,|B|=M且元素为1-N。各找一段连续子序列使和相同的。

hint:利用鸽巢原理

时间: 2024-12-28 02:12:55

骚操作之鸽巢原理的相关文章

程序设计中的组合数学——鸽巢原理

回想到高中的的组合学中,有这样的问题,12个班中有13个人参加IOI的名额(前提每班至少出一个人),那么这会有几种分法? 一个很简单的思路就是把这13个名额摊开,然后拿11个隔板插到这13个名额形成的12个空隙里,然后用组合数的公式即可计算.而鸽巢原理的简单形式就和这个模型有联系. 我们知道,如果把12只鸽子放到11个巢里面,显然有一个巢会出现两只鸽子,这显而易见,同时也是鸽巢原理的最简单的形式. 它的证明也和简单,如果我们假设11个巢穴里最多有1个鸽子,那么各自的总数最多有11个,这一12只鸽

51nod 1574 排列转换(贪心+鸽巢原理)

题意:有两个长度为n的排列p和s.要求通过交换使得p变成s.交换 pi 和 pj 的代价是|i-j|.要求使用最少的代价让p变成s. 考虑两个数字pi和pj,假如交换他们能使得pi到目标的距离减少,pj到目标的距离减少.那么应该交换他们,这是一个必要的操作,也是答案的下界. 如果每一次都能找到这样的两个数字,那么答案就是排列p中的每个数字在排列s的位置的距离差之和/2.这显然是答案的下界. 现在考虑证明这个下界是可以构造出来的. 考虑排列p中最后一个位置不对的数字,不妨设为pj,他的目标位置是p

POJ 2356 find multiple 鸽巢原理

我们在浏览一些网站,尤其是一些小说网站的时候,都会有修改页面背景颜色的地方,这个功能使用jquery很容易实现. 效果图: show you code: <!doctype html> <html> <head> <meta charset="utf-8"> <title>jquery test</title> <script src="jquery-1.11.1.min.js">&

Two progressions(CodeForces-125D)[鸽巢原理]

题意:将一列数划分为两个等差数列. 思路:首先,我要吹爆鸽巢原理!!!真的很强大的东西!!! 加入能完成题设操作,则前三个数中,必有至少两个数在同一序列,枚举三种情况(a1 a2,a2 a3,a1 a3分别为等差数列的前两项). 注:枚举情况时,如果操作失败,则将已成功生成的等差数列末项划分到另一个数列试试.(稍作思考即可) 代码如下: #include<cstdio> #include<iostream> #include<cstring> using namespa

鸽巢原理简单应用

http://poj.org/problem?id=2356 从n个数里面取出一些数,这些数的和是n的倍数.并输出这些数. 先预处理出前n个数的和用sum[i]表示前i个数的和.若某个sum[i]是n的倍数,直接输出前i个数即可. 否则说明n个数中对n取余的结果有n-1种,即余数为(1~n-1),根据鸽巢原理知必定至少存在两个sum[i]与sum[j]对n取余的结果相等.那么i+1 ~ j之间的数之和一定是n的倍数. #include <stdio.h> #include <iostre

poj 2356 Find a multiple 鸽巢原理的简单应用

题目要求任选几个自然数,使得他们的和是n的倍数. 由鸽巢原理如果我们只选连续的数,一定能得到解. 首先预处理前缀和模n下的sum,如果发现sum[i]==sum[j] 那么(sum[j]-sum[i])%n一定为0,直接输出i+1~j就够了. 为什么一定会有解,因为sum从1~n有n个数,而模n下的数只有0~n-1,把n个数放入0~n-1个数里,怎么也会有重复,所以这种构造方法一定没问题. 其实可以O(n)实现,嫌麻烦,就二重循环无脑了. #include <iostream> #includ

鸽巢原理-poj3370

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 #include <stdio.h> int main(int argc, char *argv[]) {         int c = -1, n = -1;         while (true) {         scanf("%d%d",

HDU 1205.吃糖果【鸽巢原理】【8月1】

吃糖果 Problem Description HOHO,终于从Speakless手上赢走了所有的糖果,是Gardon吃糖果时有个特殊的癖好,就是不喜欢将一样的糖果放在一起吃,喜欢先吃一种,下一次吃另一种,这样:可是Gardon不知道是否存在一种吃糖果的顺序使得他能把所有糖果都吃完?请你写个程序帮忙计算一下. Input 第一行有一个整数T,接下来T组数据,每组数据占2行,第一行是一个整数N(0<N<=1000000),第二行是N个数,表示N种糖果的数目Mi(0<Mi<=10000

POJ 2356 Find a multiple 鸽巢原理

题目来源:POJ 2356 Find a multiple 题意:n个数 选出任意个数 使得这些数的和是n的倍数 思路:肯定有解 并且解是连续的一段数 证明: 假设有m个数 a1,a2,a3...am    s1 s2 s3...sm为前缀和 s1 = a1 s2 = a1+a2 s3 = a1+a2+a3... sm = a1+a2+a3+...+am 1.如果某个前缀和si%m == 0 那么得到解 2.设x1=s1%m x2 = s2%m x3 = s3%m xm = sm%m 因为1不成