《Introductory Combinatorics Fifth Edition》学习笔记:
四个基本计数原理:
@加法原理:设集合s划分为两两互不相交的各个部分s1,s2,s3……sn,那么s的元素总个数等于各个部分的总个数之和。即|s|=|s1|+|s2|+……+|sn|.(如果允许子部分相交,则需要用容斥原理来解决)使用加法原理的技巧是:把原集合分割成容易处理的少量子集。分析:一个正整数可以进行唯一的素因子分解,比如12=2^2*3,那么12的正因子为2的指数总个数和3的指数总个数之积;3*2=6.
#include
#include
#include
using namespace std;
typedef long long LL;
const int maxn=1e8+1,maxn2=1e7;
int pri[maxn2],top=0,pow[maxn2];
bool notpri[maxn];
void getpri(){
for(int i=2;i>n){
top2=0;
memset(pow,0,sizeof(pow));
for(i=0;i
巧用乘法原理:
@减法原理:令U是一个包含A的集合,设A'=U/A={x属于U但是不属于A},称A'是A在U中的补集。|A|=|U|-|A'|.
例子:有多少个各位数字互不相同且不为0的两位数?
用乘法原理做:9*8=72.
减法原理做:两位数字一共有90个(99-9=90),存在位数有0的有(10,20……90)9个,位数相同的两位数有(11,22,33……99)9个,所以满足条件的一共有90-9-9=72个。
@除法原理:如果知道了s中的对象数目以及各部分所含对象数目的共同值,就可以确定部分的数目。k=|s|/|s(k)|.
例子(严格的说是排列的例子): 数字1,1,1,3,8能够构造多少个不同的5位数?
s=A(5,5)/A(3,3)=5*4=20.(用乘法原理同样能分析出来)