离散数学之球盒问题
1.n个不同的球,m个不同的盒子(允许空盒)
那么每个球都有对应盒子的选择:
m
n
m^n
mn
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 7;
typedef long long ll;
void solve()
{
ll n, m;
cin >> n >> m;
ll ans = 1;
while (n)//使用了快快速幂思想
{
if (n & 1) ans *= m;
n >>= 1;
m = m * m;
}
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
// int t; cin >> t; while(t--)
solve();
return 0;
}
2.n个相同的球,m个不同的盒子(允许空盒)
那么就使用隔板法,有m个盒子就有m-1个板,问题就化成在n+m-1个位置中选n个小球位置的方法数
C
(
m
+
n
−
1
,
n
)
C(m+n-1,n)
C(m+n−1,n)
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 7;
typedef long long ll;
ll C(int n, int k) {
int sum1 = 1, sum2 = 1;
for (int i = 1; i <= k; i++) {
sum1 *= i;
sum2 *= (n - k + i);
if (sum2 % sum1 == 0) {
sum2 /= sum1;
sum1 = 1;
}
}
return sum2 / sum1;
}
void solve()
{
ll n, m;
cin >> n >> m;
ll ans = C(n + m - 1, n);
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
// int t; cin >> t; while(t--)
solve();
return 0;
}
3.n个相同的球,m个不同盒子(不允许空盒)
因为不允许空盒,所以当n<m时 答案应该为0。其他情况可以使用插板法,n个小球就有n-1个空隙,m个盒子有m-1个空隙 所以问题就转化为在n-1个小球空隙中选m-1盒子空隙的位置的方案数
C
(
n
−
1
,
m
−
1
)
C(n-1,m-1)
C(n−1,m−1)
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 7;
typedef long long ll;
ll C(int n, int k) {
int sum1 = 1, sum2 = 1;
for (int i = 1; i <= k; i++) {
sum1 *= i;
sum2 *= (n - k + i);
if (sum2 % sum1 == 0) {
sum2 /= sum1;
sum1 = 1;
}
}
return sum2 / sum1;
}
void solve()
{
ll n, m;
cin >> n >> m;
ll ans = C(n - 1, m - 1);
cout << ans << endl;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
// int t; cin >> t; while(t--)
solve();
return 0;
}
4.n个不同的小球,m个相同的盒子(不允许空盒)
不允许空盒子那么就和前一个问题一样 如果n<m则答案为0, 如果n==m则答案为1。
其余可分为两种情况讨论:
1.如果n-1个球已经放入m个盒子中,那么第m个球就有m种放置方法;
2.如果n-1个1球已经放入m-1个盒子中,那么第n个球肯定放入第m个盒子中。
此问题可利用地推方法求解
f ( n , m ) = 1 ( n = = m ∣ ∣ m = = 1 ) f(n,m)=1(n==m||m==1) f(n,m)=1(n==m∣∣m==1)
f ( n , m ) = 0 ( n < m ) f(n,m)=0(n < m) f(n,m)=0(n<m)
f ( n , m ) = m ∗ f ( n − 1 , m ) + f ( n − 1 , m − 1 ) f(n,m)=m*f(n - 1,m)+f(n-1,m-1) f(n,m)=m∗f(n−1,m)+f(n−1,m−1)
5.n个不同的球,m个相同的盒子(允许空盒)
多种情况:n个球全部只放在第一个盒子,只放前两个…放前m个
f
(
n
,
m
)
=
f
(
n
,
1
)
+
f
(
n
,
2
)
+
.
.
.
+
f
(
n
,
m
)
f(n,m)=f(n,1)+f(n,2)+...+f(n,m)
f(n,m)=f(n,1)+f(n,2)+...+f(n,m)
6.n个不同的球,m个不同的盒子(不允许空盒)
较于第四个问题只是多了一个盒子的有序性,于是在第四个问题的基础上乘上盒子的全排列m!即可
7.n个相同的球,m个相同的盒子(允许空盒)
允许空盒的话则可分为两种情况,放满和不放满
f
(
n
,
m
)
=
1
(
m
=
=
1
)
f(n,m)=1 (m==1)
f(n,m)=1(m==1)
f ( n , m ) = f ( n , m − 1 ) ( n < m ) f(n,m)=f(n,m-1) (n<m) f(n,m)=f(n,m−1)(n<m)
f ( n , m ) = f ( n , m − 1 ) + f ( n − m , m ) f(n,m)=f(n,m-1)+f(n-m,m) f(n,m)=f(n,m−1)+f(n−m,m)
8.n个不同的球,m个相同的盒子(不允许空盒)
不允许空盒的话, 当n<m时, 答案为0。因为不允许空盒,所以先将m个小球各放入m个盒子里,剩余n-m个小球就按照数量分布。也就是前一问题中放满的情况
f
(
n
,
m
)
=
f
(
n
−
m
,
m
)
;
f(n,m)=f(n-m,m);
f(n,m)=f(n−m,m);