容斥原理
百科名片
编辑本段公式
也可表示为
设S为有限集,
,则
两个集合的容斥关系公式:A∪B = A+B - A∩B (∩:重合的部分)
详细推理如下:
1、 等式右边改造 = {[(A+B - A∩B)+C - B∩C] - C∩A }+ A∩B∩C
2、文氏图分块标记如右图图:1245构成A,2356构成B,4567构成C
3、等式右边()里指的是下图的1+2+3+4+5+6六部分:
那么A∪B∪C还缺部分7。
4、等式右边[]号里+C(4+5+6+7)后,相当于A∪B∪C多加了4+5+6三部分,
减去B∩C(即5+6两部分)后,还多加了部分4。
5、等式右边{}里减去C∩A (即4+5两部分)后,A∪B∪C又多减了部分5,
则加上A∩B∩C(即5)刚好是A∪B∪C。
编辑本段严格证明
对于容斥原理我们可以利用数学归纳法证明:
证明:当
时,等式成立(
证明略)。
假设
时结论成立,则当
时,
编辑本段原理1
如果被计数的事物有A、B两类,那么,A类B类元素个数总和= 属于A类元素个数+ 属于B类元素个数—既是A类又是B类的元素个数。(A∪B = A+B - A∩B)
例1 一次期末考试,某班有15人数学得满分,有12人语文得满分,并且有4人语、数都是满分,那么这个班至少有一门得满分的同学有多少人?
分析
依题意,被计数的事物有语、数得满分两类,“数学得满分”称为“A类元素”,“语文得满分”称为“B类元素”,“语、数都是满分”称为“既是A类又是B类的元素”,“至少有一门得满分的同学”称为“A类和B类元素个数”的总和。
答案
15+12-4=23
试一试
电视台向100人调查前一天收看电视的情况,有62人看过2频道,34人看过8频道,其中11人两个频道都看过。两个频道都没看过的有多少人?
100-(62+34-11)=15
编辑本段原理2
如果被计数的事物有A、B、C三类,那么,A类和B类和C类元素个数总和= A类元素个数+ B类元素个数+C类元素个数—既是A类又是B类的元素个数—既是A类又是C类的元素个数—既是B类又是C类的元素个数+既是A类又是B类而且是C类的元素个数。(A∪B∪C = A+B+C - A∩B - B∩C - C∩A + A∩B∩C)
例1
某校六⑴班有学生45人,每人在暑假里都参加
体育训练队,其中参加足球队的有25人,参加排球队的有22人,参加游泳队的有24人,足球、排球都参加的有12人,足球、游泳都参加的有9人,排球、游泳都参加的有8人,问:三项都参加的有多少人?
分析:参加足球队的人数25人为A类元素,参加排球队人数22人为B类元素,参加游泳队的人数24人为C类元素,既是A类又是B类的为足球排球都参加的12人,既是B类又C类的为足球游泳都参加的9人,既是C类又是A类的为排球游泳都参加的8人,三项都参加的是A类B类C类的总和设为X。注意:这个题说的每人都参加了体育训练队,所以这个班的总人数即为A类B类和C类的总和。
答案:25+22+24-12-9-8+X=45 解得X=3
例2
在1到1000的自然数中,能被3或5整除的数共有多少个?不能被3或5整除的数共有多少个?
分析:显然,这是一个重复计数问题(当然,如果不怕麻烦你可以分别去数3的倍数,5的倍数)。我们可以把“能被3或5
整除的数”分别看成A类元素和B类元素,能“同时被3或5整除的数(15的倍数)”就是被重复计算的数,即“既是A类又是B类的元素”。求的是“A类或B类元素个数”。我们还不能直接计算,必须先求出所需条件。1000÷3=333……1,能被3整除的数有333个(想一想,这是为什么?)同理,可以求出其他的条件。
例3
分母是1001的最简分数一共有多少个?
分析:这一题实际上就是找分子中不能与1001进行约分的数。由于1001=7×11×13,所以就是找不能被7,11,13整除的数。
解答:1~1001中,有7的倍数1001/7 = 143 (个);有11的倍数1001/11 = 91 (个),有13的倍数1001/13 = 77 (个);有7´11=77的倍数1001/77 = 13 (个),有7´13=91的倍数1001/91 = 11 (个),有11´13=143的倍数1001/43 = 7 (个).有1001的倍数1个。
由
容斥原理知:在1~1001中,能被7或11或13整除的数有(143+91+77)-(13+11+7)+1=281(个),从而不能被7、11或13整除的数有1001-281=720(个).也就是说,分母为1001的最简分数有720个。
例4
短跑
|
游泳
|
投掷
|
短跑、游泳
|
短跑、投掷
|
游泳、投掷
|
短跑、游泳、投掷
|
1 7
|
1 8
|
1 5
|
6
|
6
|
5
|
2
|
求这个班的学生共有多少人?
分析:这个班的学生数,应包括达到优秀和没有达到优秀的。
试一试:一个班有42人,参加合唱队的有30人,参加美术组的有25人,有5人什么都没有参加,求两种都参加的有多少人?
例5
在一根长的木棍上有三种刻度线,第一种刻度线将木棍分成10等份,第二种将木棍分成12等份,第三种将木棍分成15等份。如果沿每条刻度线将木棍锯断,木棍总共被锯成多少段?
分析:
很显然,要计算木棍被锯成多少段,只需要计算出木棍上共有多少条不同的刻度线,在此基础上加1就是段数了。
若按将木棍分成10等份的刻度线锯开,木棍有9条刻度线。在此木棍上加上将木棍分成12等份的11条刻度线,显然刻度线有重复的,如5/10和6/12都是1/2。同样再加上将木棍分成15等份的刻度线,也是如此。所以,我们应该按容斥原理的方法来解决此问题。用
容斥原理的那一个呢?想一想,被计数的事物有那几类?每一类的元素个数是多少?
解答
解一:(10,12,15)=60,设木棍60厘米
60÷10=6厘米,60÷12=5厘米,60÷15=4厘米
10等分的为第一种刻度线,共10-1=9条
12等分的为第二种刻度线,共12-1=11条
15等分的为第三种刻度线,过15-1=14条
第一种与第二种刻度线重合的(6,5)=30,60÷30-1=2-1=1条
第一种与第三种刻度线重合的(6,4)=12,60÷12-1=5-1=4条
第二种与第三种刻度线重合的(5,4)=20,60÷20-1=3-1=2条
三种刻度线重合的没有,(6、5、4)=60
因此,共有刻度线9+11+14-1-4-2=27条,木棍总共被锯成27+1=28段。
解二:总长看成单位1分别分成10、12、15段。1/10与1/12的
最小公倍数1/2,1/10与1/15的最小公倍数1/5,1/12与1/15的最小公倍数1/3,1/10,1/12和1/15的最小公倍数为1,有10+12+15-(2+5+3)+1=28
解三:
10、12、15的最小公倍数是60,假设木棍就是长60,
1、那么,分成10等份的每份6,刻度就是
0,6,12,18,24,30,36,42,48,54,60
2、分成12等分的每份就是5,
0,5,10,15,20,25,30,35,40,45,50,55,60
3、分成15等分的每份就是4,
0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60
4、把相同刻度的合并,就是有刻度如下:
0,4,5,6,8,10,12,15,16,18,20,24,25,28,30,32,35,36,40,42,44,45,48,50,52,54,55,56,60
Card Collector
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1708 Accepted Submission(s): 780
Special Judge
Problem Description
In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, for example, if you collect all the 108 people in the famous novel Water Margin, you will win an amazing award.
As a smart boy, you notice that to win the award, you must buy much more snacks than it seems to be. To convince your friends not to waste money any more, you should find the expected number of snacks one should buy to collect a full suit of cards.
As a smart boy, you notice that to win the award, you must buy much more snacks than it seems to be. To convince your friends not to waste money any more, you should find the expected number of snacks one should buy to collect a full suit of cards.
Input
The first line of each test case contains one integer N (1 <= N <= 20), indicating the number of different cards you need the collect. The second line contains N numbers p1, p2, ..., pN, (p1 + p2 + ... + pN <= 1), indicating the possibility of each card to appear in a bag of snacks.
Note there is at most one card in a bag of snacks. And it is possible that there is nothing in the bag.
Note there is at most one card in a bag of snacks. And it is possible that there is nothing in the bag.
Output
Output one number for each test case, indicating the expected number of bags to buy to collect all the N different cards.
You will get accepted if the difference between your answer and the standard answer is no more that 10^-4.
You will get accepted if the difference between your answer and the standard answer is no more that 10^-4.
Sample Input
1 0.1 2 0.1 0.4
Sample Output
10.000 10.500
Source
当时看到,这一题,一点思路都没有啊,后来,发现是用容斥原理,这个表示没用过,补上这个知识点!
- #include <iostream>
- #include <stdio.h>
- #include <string.h>
- using namespace std;
- double p[25];
- int main()
- {
- int n,i,flag,j,k,all,cnt;
- double sum,s,temp;
- while(scanf("%d",&n)!=EOF)
- {
- flag=1;
- for(i=0;i<n;i++)
- {
- scanf("%lf",&p[i]);
- }
- sum=0;
- flag=1;
- all=1<<n;
- for(i=1;i<all;i++)
- {
- cnt=0;
- temp=0;
- for(j=0;j<n;j++)
- {
- if(i&(1<<j))//相交
- {
- temp+=p[j];cnt++;
- }
- }
- if(cnt&1)//奇加偶减
- sum+=1.0/temp;
- else
- sum-=1.0/temp;
- }
- printf("%.4f\n",sum);
- }
- return 0;
- }
- 再来一个状态压缩dp,这里我们可以推出dp[n]=1+all dp[n](空的)+all dp[n](重复的)+all dp[k](没有但是加一个就有了);这样就好做了,好像这一题还非要写成输出4位,输出3位还是错的,样例应该是有问题的!很坑啊,有木有!
- #include <stdio.h>
- #include <string.h>
- #include <iostream>
- using namespace std;
- double p[25],dp[1<<20];
- int main ()
- {
- int n,i,j,all;
- double allp,tempallp,sum;
- while(scanf("%d",&n)!=EOF)
- {
- allp=0;
- for(i=0;i<n;i++)
- {
- scanf("%lf",&p[i]);
- allp+=p[i];
- }
- all=1<<n;
- dp[0]=0;
- for(i=1;i<all;i++)
- {
- tempallp=allp;
- sum=1;//买了一袋
- for(j=0;j<n;j++)
- {
- if(i&(1<<j))
- {
- sum+=p[j]*dp[i^(1<<j)];
- }
- else
- {
- tempallp-=p[j];
- }
- }
- dp[i]=sum/tempallp;
- }
- printf("%.4f\n",dp[all-1]);
- }
- return 0;
- }