原题网址
由于某些原因,这个网址会进不去…
题目描述
将整数n分成k份,且每份不能为空,任意两种分法不能相同(不考虑顺序)。
例如:
n
=
7
,
k
=
3
(
6
<
n
≤
200
,
2
≤
k
≤
6
)
n=7,k=3 (6<n\le 200,2\le k\le 6)
n=7,k=3 (6<n≤200,2≤k≤6),下面三种分法被认为是相同的。
1
,
1
,
5
;
1
,
5
,
1
;
5
,
1
,
1
。
1,1,5;\ 1,5,1;\ 5,1,1。
1,1,5; 1,5,1; 5,1,1。
问有多少种不同的分法。
注意
所有题均要写成搜索
格式
输入格式
输入两个数, n , k n,k n,k。
输出格式
一个整数,即不同的分法个数。
样例
输入样例
7 3
输出样例
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;
解题思路
尽管这道题目可以用递推,但题目要求我们使用搜索,这里只好讲一下搜索的做法:由题可知,分法不能相同且不考虑顺序,因此搜索时,我们可以假定每次搜索得到的数都比上一次得到的大,这样就不会有重复的分法出现。并且题目数据较小,因此每次搜索不需要任何剪枝操作。
Code
#include<iostream>
using namespace std;
int n, k, ans;
void input() // 输入
{
cin>>n>>k;
}
void dfs(int dep, int n, int s) // dep表示搜索深度(已经搜了几个数),n表示上一次选择的数,s表示剩下的数
{
if (dep == k) // 最后一次循环
{
if (n <= s) ans ++; // 当最后剩下的数比上一次选择的数大,说明这种方案可行
return;
}
for (int i = n; i <= (n + s) / 2; i ++) // *
{
dfs(dep + 1, i, s - i);
}
}
void output() // 输出
{
cout<<ans;
}
int main()
{
input();
dfs(1, 1, n); // 为了*行的for循环正确从1开始,这里的参数int n我填了1
output();
return 0;
}
大功告成 ∼ \sim ∼