数论 Day 12

数论是个好东西


今天讲的是组合计数


 

组合计数

组合数学主要是研究一组离散对象满足一定条件的安排的存在性、构造及计数问题。计数理论是狭义组合数学中最基本的一个研究方向,主要研究的是满足一定条件的排列组合及计数问题。组合计数包含计数原理、计数方法、计数公式。

组合计数基本原理
加法原理
如果一个目标的实现可以在种不同的情况下完成,且对于第种情况又有种不同的方法,那么总的方法数为:

其中,每种条件达成都能单独实现目标,而不依赖其他条件;任意情况的任两种方法都是唯一的。

乘法原理
如果一个目标的实现需要经过个步骤,对于第步有种不同的方式实现,那么总的方法数为:

其中,步骤之间可能存在拓扑关系,但每个步骤都必不可少;每一步内选择何种方式不受其他步骤影响。

容斥原理

组合计数最重要的事不重复不遗漏。但一般情况下总会出现很多的重复计算,又或者在分类讨论中遗漏某种情况。这时我们就需要容斥原理。容斥原理的基本思想是:先不考虑重复,得出所有的情况数,然后再排除重复计算的部分,由于每一步都有理可循,正确运用即可做到不遗漏不重复。

公式:

设是有限集合,,,则

容斥公式可以由如下集合运算的基本公式(德摩根公式)以及数学归纳法证明得到:

 

组合计数基本公式

排列数公式

从n个不同元素中任取m(m≦n)个元素排成一列(考虑元素先后出现次序),叫做从n个不同元素中取出m个元素的一个排列。排列的总数即为排列数,即叫做从n个不同元素中取出m个元素的排列数(number of permutations)。排列数用符号P(Permutation)或者A(Arrangement)表示。

表示从个元素里取出个并排列(要考虑顺序)得到的方案数。
拓展
循环排列:又称圆排列,指从个元素里取出个元素构成循环排列的排列数,把个元素分成类,第类元素的个数为,此时个元素的排列数
组合数公式

从n个不同元素中任取m(m≦n)个元素构成一组(不考虑顺序),叫做从n个不同元素中取出m个元素的一个组合。组合的总数即为组合数,即叫做从n个不同元素中取出m个元素的组合数(number of combinations)。组合数用符号C表示:

表示从个元素里取出个构成一组(不考虑顺序)得到的方案数,也可以用二项式系数()表示。
拓展
类元素,每类元素个数均为无限,从这些元素中取出个的组合数为
组合数的性质
组合数递推式:二项式系数:

 

错排公式

错排问题也是组合数学的经典问题之一。错排即错误的排列:对于n个元素构成的一种排列,对其重新排序使得每一个元素都不在原来的位置上,这样的排列就称为原排列的一个错排。n个元素的一个排列的错排数记为D(n),则:

取整,由的展开式推出

组合计数常用技巧

捆绑法

当要求某些元素必须相邻时,先把他们看作一个整体,然后把整体当成一个元素和其他元素一起考虑。要注意:整体内部也有顺序。

插空法

当要求某些元素不能相邻时,可以先把其他元素排好,然后再把要求不相邻的元素插入到已排好的元素的空隙或两端。

隔板法

在解决若干相同元素分组问题时,若要求每组至少一个元素,则可以转化为在排成一列的这些元素中插入组数减1个“隔板”,达到分组目的。

例:个小球个盒子,每个盒子不为空,则有种方案;若盒子不要求非空,则可由引入个球,隔板法解决后从每个盒子里各取走一个球,方案数为

以上只是课件,不要太在意。

今天做题,一上来A题就是个水题,输入数据 <= 100 !!!我的天 !!!

题意:

给定一个N,K,使K个整数之和等于N,求方案数mod 1,000,000的结果

原题面:

Larry is very bad at math — he usually uses a calculator, which
worked well throughout college. Unforunately, he is now struck in
a deserted island with his good buddy Ryan after a snowboarding
accident.
They’re now trying to spend some time figuring out some good
problems, and Ryan will eat Larry if he cannot answer, so his fate
is up to you!
It’s a very simple problem — given a number N, how many ways
can K numbers less than N add up to N?
For example, for N = 20 and K = 2, there are 21 ways:
0+20
1+19
2+18
3+17
4+16
5+15
...
18+2
19+1
20+0
Input
Each line will contain a pair of numbers N and K. N and K will both be an integer from 1 to 100,
inclusive. The input will terminate on 2 0’s.
Output
Since Larry is only interested in the last few digits of the answer, for each pair of numbers N and K,
print a single number mod 1,000,000 on a single line.
Sample Input
20 2
20 2
0 0
Sample Output
21
21
How do you add? UVA - 10943

思路:

简单,DP都能做。

明显隔板法

因为可以为0

所以要加k个0

所以就有n + k - 1个空

有k - 1个板

答案为 C(n - k + 1, k - 1)

代码:

#include <algorithm>
#include <cstring>
#include <iostream>#define N 220
#define mod 1000000
#define ll long long
using namespace std;
​
int n,k,f[N][N];
int dfs(int a,int b)
{
    if(a < b)
        return 0;
    if(b == 0)
        return 1;
    if(a == 0)
        return 1;
    if(f[a][b])
        return f[a][b];
​
    return f[a][b] = (dfs(a - 1, b - 1) + dfs(a - 1, b)) % mod;
}
​
int main()
{
    while(true)
    {
        scanf("%d %d",&n,&k);
        if(!n && !k)
            break;
​
        printf("%d\n",dfs(n + k - 1, n));
    }
    return 0;
}

未完待续

转载于:https://www.cnblogs.com/wnfs/p/11197892.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值