这章没有什么算法可言,单纯的你懂了原理后会不会运用(反正我基本没怎么用过 ̄ 3 ̄)

有366人,那么至少有两人同一天出生(好孩子就不要在意闰年啦( ̄▽ ̄"))

有13人,那么至少有两人同一月出生

这就是抽屉原理

抽屉原理:把n+1个物品放到n个抽屉里,那么至少有两个物品在同一个抽屉里

鸽巢原理:把n+1个鸽子放到n个鸽巢里,那么至少有两个鸽子在同一个鸽巢里

球盒原理:把n+1个小球放到n个球盒里,那么至少有两个小球在同一个球盒里

(你看,我都帮你们解释里一遍(≧︶≦*))

其实抽屉原理有两个

第一抽屉原理

原理1: 把多于n+k个的物体放到n个抽屉里,则至少有一个抽屉里的东西不少于两件。

原理2 :把多于mn(m乘以n)+1(n不为0)个的物体放到n个抽屉里,则至少有一个抽屉里有不少于(m+1)的物体。

原理3 :把无穷多件物体放入n个抽屉,则至少有一个抽屉里 有无穷个物体。
 
原理1 、2 、3都是第一抽屉原理的表述。

第二抽屉原理

把(mn-1)个物体放入n个抽屉中,其中必有一个抽屉中至多有(m—1)个物体(例如,将3×5-1=14个物体放入5个抽屉中,则必定有一个抽屉中的物体数少于等于3-1=2)。

原理懂了,但是你会运用吗?

来看这一题

cf 577B

http://codeforces.com/problemset/problem/577/B

Modulo Sum

给你一个序列a1,a2...an,再给你一个数字m

问你能不能从中选出几个数,把他们相加,令这个和能够整除m

能就是输出YES,不能就输出NO

不知道你有木有思路(O ° ω ° O )

正常讲肯定是dp咯,加一点剪枝,勉强卡过了(因为CF上面都是单组数据,多组可能就超时了)

AC代码:

 #include<cstdio>
#include<cstring>
const int N = (int)1e6 + ;
int n, m;
int a[N];
bool dp[][];//滚动数组
bool work(){
dp[][a[]] = true;
for(int i = ; i < n; i ++){
memset(dp[i & ], , sizeof(bool)*);
dp[i & ][a[i]] = true;
for(int j = ; j < m; j ++){
if(dp[(i-) & ][j]){
dp[i & ][(j + a[i]) % m] = true;
dp[i & ][j] = true;
}
}
if(dp[i & ][]) return true;
}
return dp[(n-) & ][];
}
int main(){
scanf("%d%d", &n, &m);
for(int i = ; i < n; i ++){
scanf("%d", &a[i]);
a[i] %= m;
}
puts(work() ? "YES" : "NO");
}

其实这题的n虽然范围大,但是我们可以加一个判断,n>m的话,必然输出YES

为什么?根据抽屉原理呗

先求前缀和求余m,

如果有m+1个数,那么就会产生m+1个前缀和,求余完m,就会有m+1个余数

我们知道求余完m会产生0~m-1总共m个余数

那么根据抽屉原理,至少有两个相同的余数

那么他们之间的数的和求余m就肯定是0,所以n>m的话,必然输出YES

比如

取两个下标i和j(i < j)

(a1+a2+...+ai) % m = k

(a1+a2+...+aj) % m = k

那么(ai+...+aj) %m = 0

所以问题解决啦

AC代码:

 #include<cstdio>
#include<cstring>
const int N = (int)1e6 + ;
int n, m;
int a[N];
bool dp[][];//滚动数组
bool work(){
if(n > m) return true;//多加这一句,TLE的代码说不定就能AC
dp[][a[]] = true;
for(int i = ; i < n; i ++){
memset(dp[i & ], , sizeof(bool)*);
dp[i & ][a[i]] = true;
for(int j = ; j < m; j ++){
if(dp[(i-) & ][j]){
dp[i & ][(j + a[i]) % m] = true;
dp[i & ][j] = true;
}
}
if(dp[i & ][]) return true;
}
return dp[(n-) & ][];
}
int main(){
scanf("%d%d", &n, &m);
for(int i = ; i < n; i ++){
scanf("%d", &a[i]);
a[i] %= m;
}
puts(work() ? "YES" : "NO");
}

这个原理懂了,一定要学会用,要不然碰上别的题目一样不会(又在黑自己。。。( ̄▽ ̄"))

ACM数论之旅14---抽屉原理,鸽巢原理,球盒原理(叫法不一又有什么关系呢╮(╯▽╰)╭)的更多相关文章

  1. acm数论之旅--中国剩余定理

    ACM数论之旅9---中国剩余定理(CRT)(壮哉我大中华╰(*°▽°*)╯)   中国剩余定理,又名孙子定理o(*≧▽≦)ツ 能求解什么问题呢? 问题: 一堆物品 3个3个分剩2个 5个5个分剩3个 ...

  2. acm数论之旅--组合数(转载)

    随笔 - 20  文章 - 0  评论 - 73 ACM数论之旅8---组合数(组合大法好(,,• ₃ •,,) )  补充:全错排公式:https://blog.csdn.net/Carey_Lu/ ...

  3. acm数论之旅--欧拉函数的证明

    随笔 - 20  文章 - 0  评论 - 73 ACM数论之旅7---欧拉函数的证明及代码实现(我会证明都是骗人的╮( ̄▽ ̄)╭) https://blog.csdn.net/chen_ze_hua ...

  4. acm数论之旅(转载) -- 逆元

    ACM数论之旅6---数论倒数,又称逆元(我整个人都倒了( ̄﹏ ̄))   数论倒数,又称逆元(因为我说习惯逆元了,下面我都说逆元) 数论中的倒数是有特别的意义滴 你以为a的倒数在数论中还是1/a吗 ( ...

  5. acm数论之旅--数论四大定理

    ACM数论之旅5---数论四大定理(你怕不怕(☆゚∀゚)老实告诉我)   (本篇无证明,想要证明的去找度娘)o(*≧▽≦)ツ ----------数论四大定理--------- 数论四大定理: 1.威 ...

  6. poj2356 Find a multiple(抽屉原理|鸽巢原理)

    /* 引用过来的 题意: 给出N个数,问其中是否存在M个数使其满足M个数的和是N的倍数,如果有多组解, 随意输出一组即可.若不存在,输出 0. 题解: 首先必须声明的一点是本题是一定是有解的.原理根据 ...

  7. POJ 3370. Halloween treats 抽屉原理 / 鸽巢原理

    Halloween treats Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7644   Accepted: 2798 ...

  8. POJ 2356. Find a multiple 抽屉原理 / 鸽巢原理

    Find a multiple Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7192   Accepted: 3138   ...

  9. ACM数论之旅13---容斥原理(一切都是命运石之门的选择(=゚ω゚)ノ)

    容斥原理我初中就听老师说过了,不知道你们有没有听过(/≧▽≦)/ 百度百科说: 在计数时,必须注意没有重复,没有遗漏. 为了使重叠部分不被重复计算,人们研究出一种新的计数方法. 这种方法的基本思想是: ...

随机推荐

  1. Oracle保存带&的数据

    在SQL*Plus中默认的"&"表示替代变量,也就是说,只要在命令中出现该符号,SQL*Plus就会要你输入替代值.这就意味着你无法将一个含有该符号的字符串输入数据库或赋给 ...

  2. 有哪些 Bootstrap 的学习案例?

    bootstrap经典实用案例 bootstrap经典实用案例(非常详细),从菜鸟到高手的过程是艰辛的,你渴望救助.这本教程就是你无言的助手,默默的帮你到永远. 带奋斗一起飞翔,因为有了它,让我拥有理 ...

  3. centos6.5部署gitlab

    安装过程参考: https://www.cnblogs.com/wenwei-blog/p/5861450.html https://ehlxr.me/2016/07/31/CentOS-%E7%B3 ...

  4. Spring boot jpa @Column命名大小写问题

    一.问题 驼峰命名会被自动转成数据库下划线命名,指定@Column的name也不起作用 举例: @Column(nullable = false,name = "resolvedDate&q ...

  5. jQuery中attr()函数 VS prop()函数

    http://www.365mini.com/page/jquery-attr-vs-prop.htm 在jQuery中,attr()函数和prop()函数都用于设置或获取指定的属性,它们的参数和用法 ...

  6. tabindex 属性

    tabindex 属性规定元素的 tab 键控制次序(当 tab 键用于导航时). 语法:<element tabindex="number">规定元素的 tab 键控 ...

  7. JDBC多表操作

    一.一对多关系:部门管理系统 1.数据库 create table department ( id ) primary key, name ) ); create table employee ( i ...

  8. Windows下Redis安装及使用

    1.下载安装Redis(安装直接下一步就行,此步骤省略) Redis-x64-3.2.100.exe 2.Redis使用 安装目录如下: ①cmd启动redis: ②将redis安装为服务 此时如果安 ...

  9. WPF中的颜色转换

    HEX16色转Bursh: Brush brush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFFFF ...

  10. Python中的异常(Exception)处理

    异常 当你的程序出现例外情况时就会发生异常(Exception).例如,当你想要读取一个文件时,而那个文件却不存在,怎么办?又或者你在程序执行时不小心把它删除了,怎么办?这些通过使用异常来进行处理. ...