放球问题

题目链接

P1287 盒子与球
4002. 构造数组

放球问题

放球问题: 把 n个球放到 m个盒子里的方案数

问题编号 小球 盒子 条件 空盒 方案数
互不相同 互不相同 \(n \ge m \ge 1\) 允许 \(m^n\)
互不相同 互不相同 \(m > n \ge 1\) 允许 \(m^n\)
互不相同 完全相同 \(n \ge m \ge 1\) 不允许 \(S(n,m)\)
互不相同 完全相同 \(m>n \ge 1\) 不允许 \(0\)
互不相同 互不相同 \(n \ge m \ge 1\) 不允许 \(m!S(n,m)\)
互不相同 互不相同 \(m>n \ge 1\) 不允许 \(0\)
互不相同 完全相同 \(n \ge m\ge 1\) 允许 \(S(n,1)+S(n,2)+\dots +S(n,m)\)
互不相同 完全相同 \(m > n\ge 1\) 允许 \(S(n,1)+S(n,2)+\dots +S(n,n)\)
完全相同 互不相同 \(n \ge m\ge 1\) 允许 \(C_{m+n+1}^n\)
完全相同 互不相同 \(m > n \ge 1\) 允许 \(C_{m+n+1}^n\)
完全相同 互不相同 \(n \ge m\ge 1\) 不允许 \(C_{n-1}^{m-1}\)
完全相同 互不相同 \(m > n\ge 1\) 不允许 \(0\)
完全相同 完全相同 \(n \ge m\ge 1\) 允许 \(G(x)=\frac{1}{x^1+x^2+\dots+x^n}\)
完全相同 完全相同 \(m > n\ge 1\) 允许 $$
完全相同 完全相同 \(n \ge m\ge 1\) 不允许 $$
完全相同 完全相同 \(m > n\ge 1\) 不允许 \(0\)
n个球是否有区别 m个盒是否有区别 是否允许空盒 n是否大于m 方案数 简要解释
img 每个球有m种可能
img 每个球有m种可能
img 类比盒无区别时,再乘以盒的可能排列
盒比球多,必有空盒
img 枚举有球盒的数量,再利用斯特林数
img 枚举有球盒的数量,再利用斯特林数
img 根据斯特林数定义
盒比球多,必有空盒
img 插板法或根据可重组合计算公式
img 同上
img 先给每盒放一球,然后利用n-m个球,m个盒子有空盒的解
盒比球多,必有空盒
imgimg的系数 母函数方法
imgimg的系数 母函数方法
imgimg的系数 母函数方法
盒比球多,必有空盒

例题

4002. 构造数组(⑨⑩)

题目描述

现在需要构造一对数组 \((a,b)\),要求:

  • 数组 \(a\) 和数组 \(b\) 的长度都为 \(m\)
  • 两个数组中的元素的取值范围都是 \([1,n]\)
  • \(∀i∈[1,m],a_i≤b_i\)
  • 数组 \(a\) 中元素非严格单调递增。
  • 数组 \(b\) 中元素非严格单调递减。
  • 请问,共能构造出多少对满足条件的数组?

输出对 \(10^9+7\) 取模后的结果。

输入格式

一行,两个整数 \(n,m\)

输出格式

一个整数,表示满足条件的数组对的数量对 \(10^9+7\) 取模后的结果。

数据范围

前三个测试点满足,\(1≤n,m≤10\)
所有测试点满足,\(1≤n≤1000,1≤m≤10\)

输入样例:

2 2

输出样例:

5

解题思路

  • 放球问题

由于 \(a_m \leq b_m\),且 \(b\) 数组非严格单调递减,\(a\) 数组非严格单调递增,所以完全可以将 \(a\) 数组翻转并接在 \(b\) 数组后面,等价于在 \([1,n]\) 选择 \(2m\) 个数,构成非严格单调递减序列的方案数,即将 \(2m\) 个无区别的小球放入 \(n\) 个有区别的盒子且允许有空盒的方案数,组合数学模板题:放球问题
具体分析如下:
隔板法。\(n\) 个盒子相当于 \(n-1\) 个隔板,即 \(n-1\) 个隔板确定 \(n\) 个盒子,问题等价于从 \(n-1+2m\) 个隔板和球里面再另外选出 \(n-1\) 个隔板,这样就将球分成了 \(n\) 份,放入对应的盒子中~

  • 时间复杂度:\(O(mlog(mod))\)

代码

#include<bits/stdc++.h>
using namespace std;
const int mod=1e9+7;
int n,m;
int ksm(int a,int b)
{
    int res=1;
    for(;b;b>>=1)
    {
        if(b&1)res=1ll*res*a%mod;
        a=1ll*a*a%mod;
    }
    return res;
}
int C(int a,int b)
{
    int res=1;
    for(int i=a,j=1;j<=b;j++,i--)
    {
        res=1ll*res*i%mod;
        res=1ll*res*ksm(j,mod-2)%mod;
    }
    return res;
}
int main()
{
    scanf("%d%d",&n,&m);
    printf("%d",C(2*m+n-1,2*m));
    return 0;
}

P1287 盒子与球(⑤)

题目描述

现有 \(r\) 个互不相同的盒子和 \(n\) 个互不相同的球,要将这 \(n\) 个球放入 \(r\) 个盒子中,且不允许有空盒子。请求出有多少种不同的放法。

两种放法不同当且仅当存在一个球使得该球在两种放法中放入了不同的盒子。

输入格式

输入只有一行两个整数,分别代表 \(n\)\(r\)

输出格式

输出一行一个整数代表答案。

输入

3 2

输出

6

说明/提示

有两个盒子(编号为 \(1, 2\))和三个球(编号为 \(1, 2, 3\)),共有六种方案,分别如下:

盒子编号 方案 1 方案 2 方案 3 方案 4 方案 5 方案 6
盒子 \(1\) 小球 \(1\) 小球 \(2\) 小球 \(3\) 小球 \(2, 3\) 小球 \(1, 3\) 小球 \(1, 2\)
盒子 \(2\) 小球 \(2, 3\) 小球 \(1, 3\) 小球 \(1, 2\) 小球 \(1\) 小球 \(2\) 小球 \(3\)

数据规模与约定

对于 \(100\%\) 的数据,保证 \(0 \leq r \leq n \leq 10\),且答案小于 \(2^{31}\)

  • 时间复杂度:\(O(nr)\)

代码

#include<bits/stdc++.h>
using namespace std;
int n,m;
int f[11][11];
int main()
{
    scanf("%d%d",&n,&m);
    f[0][0]=1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            f[i][j]=f[i-1][j-1]+f[i-1][j]*j;
    int res=1;
    for(int i=2;i<=m;i++)res*=i;
    printf("%d",res*f[n][m]);
    return 0;
}
posted @ 2021-10-25 22:59  zyy2001  阅读(180)  评论(0编辑  收藏  举报