题目:
将 𝑛 分成 𝑚 个大于 0 的不同数的和, 1 2 同 2 1 视作相同的划分。
按照字典序输出所有方案。数据保证存在解,即不会出现 1+2+⋯𝑚>𝑛 的情况
输入数据: 个数 𝑛 , 𝑚 ( 1≤𝑚≤10 , 1≤𝑛≤50 )。1+2+...m>n
输出数据:
按照字典序,输出所有方案。数字之间,用空格划分。
数据范围:
对于 100% 的数据, 1≤𝑚≤10 , 1≤𝑛≤50 。
解题思路:
初始问题为:将 𝑛 分为若干个大于 0 的数,考虑如何进行问题转化。
当第一个数选择了 1 时,问题转为了将 𝑛−1 分为若干个大于等于 1 的数。
当第一个数选择了 3 时,问题转为了将 𝑛−3 分为若干个大于等于 3 的数。
当第一个数选择了 𝑖 时,问题转为了将 𝑛−𝑖 分为若干个大于等于 𝑖 的数。
这样,选出的数字保持升序,就不会重复的情况,我们将每一个选择的数记录在数组中。
因此增加一个参数变量 𝑚𝑖𝑛,记录已选择数字中最大的值 。每次循环 𝑚𝑖𝑛−>𝑛−𝑠𝑢𝑚 作为当前位置所选择的数字进行递归。
当 𝑛=0 时终止递归,输出所有已经选择的数字。
代码:
#include<bits/stdc++.h>
using namespace std;
int nums[21];
void Dfs(int n, int min, int index) {
if (n == 0) {
for (int i = 0; i < index; i++)
cout << nums[i] << " ";
cout << endl;
return;
}
for (int i = min; i <= n; i++) {
nums[index] = i;
Dfs(n - i, i, index + 1);
}
}
int main() {
int n;
cin >> n;
Dfs(n, 1, 0);
return 0;
}
注:本文来源于51NOD,为@小罐头甜编辑