来博客园的第一篇博客
以后就放弃csdn了,就来这里记录自己的成长,就当成一个树洞吧,开心与难过,学习与生活,进步与成长,留下时间的痕迹!冲!冲!冲!
今天就写一篇dfs+回溯的题,去问大佬,大佬5分钟不到就把代码打出来了,感觉自己是个fw,哎不管了加油吧,希望自己有一天也可以变强!
自然数的拆分问题
题目描述
任何一个大于 \(1\) 的自然数 \(n\),总可以拆分成若干个小于 \(n\) 的自然数之和。现在给你一个自然数 \(n\),要求你求出 \(n\) 的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。
输入格式
输入:待拆分的自然数 \(n\)。
输出格式
输出:若干数的加法式子。
样例 #1
样例输入 #1
7
样例输出 #1
1+1+1+1+1+1+1
1+1+1+1+1+2
1+1+1+1+3
1+1+1+2+2
1+1+1+4
1+1+2+3
1+1+5
1+2+2+2
1+2+4
1+3+3
1+6
2+2+3
2+5
3+4
提示
数据保证,\(1\le n\le 8\)。
dfs中需要两个参数,一个用来记录当前剩余要拆分的数,一个用于记录当前拆分的最大数,因为要按字典序输出,所以我们每次枚举下一个要拆分的数都从当前最大数开始枚举,比当前最大数小的数不能排在当前最大数的后面,记得回溯,需要恢复现场。
#include <iostream>
using namespace std;
const int N = 10;
int a[N], n, m;
inline void dfs(int n, int k)
{
if(n == 0)
{
if(m == 1) return ;
for(int i = 1; i < m; ++ i) cout << a[i] << "+" ;
cout << a[m] << endl;
}
for(int i = k; i <= n; ++i)
{
a[++ m] = i;
dfs(n - i, i);
m --;
}
}
int main()
{
cin >> n;
dfs(n, 1);
return 0;
}