遞歸練習 數的劃分

題目來源:牛客網

數的劃分
時間限制: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,那這種情況就得跳出了。所以剪枝,避免浪費時間。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章