[递推]C. 【例题3】数的划分
C . 【 例 题 3 】 数 的 划 分 C. 【例题3】数的划分 C.【例题3】数的划分
题目描述
将整数 n n n 分成 k k k 份,且每份不能为空,任意两个方案不相同(不考虑顺序)。
例如: n = 7 n=7 n=7, k = 3 k=3 k=3,下面三种分法被认为是相同的:
1 , 1 , 5 ; 1 , 5 , 1 ; 1 , 1 , 5. 1,1,5;~~~~1,5,1;~~~~1,1,5. 1,1,5; 1,5,1; 1,1,5.
问有多少种不同的分法。
输入格式
两个整数, n n n和 k k k 。
输出格式
输出不同的分法数。
样例
输入样例
7 3 7 ~~~3 7 3
输出样例
4 4 4
样例说明
四种分法为: 1 , 1 , 5 ; 1 , 2 , 4 ; 1 , 3 , 3 ; 2 , 2 , 3. 1,1,5;~~~~ 1,2,4; ~~~~1,3,3;~~~~ 2,2,3. 1,1,5; 1,2,4; 1,3,3; 2,2,3.
题目解析
看题面,首先想到递推.
设
t
(
n
,
k
)
为
t(n,k)为
t(n,k)为整数
n
n
n分为
k
k
k份的不同分法的数量.
因为不能为空,那么最小就只能分到
1
1
1.
那么我们就可以得出:
t
(
n
,
k
)
=
1
(
n
=
=
k
)
t(n,k)=1~~~(n==k)~~~~~~~~~~~~
t(n,k)=1 (n==k) (因为每份最多都是
1
1
1)
t
(
n
,
k
)
=
0
(
n
<
k
)
t(n,k)=0~~~(n<k)~~~~~~~~~~~~~~~
t(n,k)=0 (n<k) (因为就算每份都只放
1
1
1也不够放,而且都不能为空)
然后我们考虑两种情况
- 有一份是装有 1 1 1的:那么就有 t ( n − 1 , k − 1 ) t(n-1,k-1) t(n−1,k−1)种情况
- 没有一份是装有 1 1 1的:那么就有 t ( n − k , k ) t(n-k,k) t(n−k,k)种情况
那么就能得出递推式:
t
(
n
,
k
)
=
{
t
(
n
,
k
)
=
1
(
n
=
=
k
)
t
(
n
,
k
)
=
0
(
n
<
k
)
t
(
n
,
k
)
=
t
(
n
−
1
,
k
−
1
)
+
t
(
n
−
k
,
k
)
t(n,k) = \left\{\begin{matrix} & t(n,k)=1~~~~~~~~~~~~~(n==k)\\ & t(n,k)=0~~~~~~~~~~~~~~~~(n<k)\\ & t(n,k)=t(n-1,k-1)+t(n-k,k)\\ \end{matrix}\right.
t(n,k)=⎩⎨⎧t(n,k)=1 (n==k)t(n,k)=0 (n<k)t(n,k)=t(n−1,k−1)+t(n−k,k)
Code
#include <bits/stdc++.h>
using namespace std;
int n, k, t[205][10];
int main ()
{
scanf ("%d%d", &n, &k);
memset (t, 0, sizeof (t));
for (int i = 1; i <= n; ++ i)
{
for (int j = 1; j <= k; ++ j)
{
if (i == j) t[i][j] = 1; //每个都分1
else if (i < j) t[i][j] = 0; //每个都分1也不够
else t[i][j] = t[i - 1][j - 1]/*至少有一个份为1的方案数*/ + t[i - j][j]/*当没有任何一份为1时的方案数*/;
}
}
printf ("%d", t[n][k]);
return 0;
}