递归练习 数的划分

题目来源:牛客网

数的划分
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述

将整数n分成k份,且每份不能为空,任意两份不能相同(不考虑顺序)。 例如:n=7,k=3,下面三种分法被认为是相同的。 1,1,5;
1,5,1; 5,1,1; 问有多少种不同的分法。

输入:

n,k ( 6 < n ≤ 200,2 ≤ k ≤ 6 )

输出:

一个整数,即不同的分法。

输入描述:

两个整数 n,k ( 6 < n ≤ 200, 2 ≤ k ≤ 6 )

输出描述:

1个整数,即不同的分法。

AC代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
typedef long long LL;
using namespace std;
const int MAXN = 1e7;
int n, k, cnt;
// st为上一个位置的数字,要保证非降序排列才能不重不漏
// sum代表各个位的数字和,用来判断
// u从1开始 
void dfs(int u, int st, int sum) {
	if(u > k) {
		if(sum == n) {
			cnt++;
		}
		return;
	}
	// for循环剪枝优化 
	// 如果剩下的位数 * 最小的数 + sum > n 则需要剪枝 
	for(int i = st; i * (k - u + 1) + sum <= n; i++) {
		dfs(u + 1, i, sum + i);
	}
}
int main() {
	cin >> n >> k;
	dfs(1, 1, 0);
	cout << cnt << endl;
	return 0;
}

剪枝情况讲解:如果当前情况为:2 _ _ _ ,则第二位得从2开始选,假设后三位都选 2 ,总和 sum > n,那这种情况就得跳出了。所以剪枝,避免浪费时间。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章