C/C++语言100题练习计划 75——自然数拆分问题(DFS算法实现)

名人说:故立志者,为学之心也;为学者,立志之事也。—— 王阳明
进度:C/C++语言100题练习计划专栏,目前75/100

🥇C/C++语言100题练习专栏计划目的:巩固练习C/C++语言,增强上机、动手实践能力,交流学习!

一、问题呈现

1.问题描述

Problem Description
任何一个大于11的自然数n,总可以拆分成若干个小于n的自然数之和。现在给你一个自然数n,要求你求出n的拆分成一些数字的和。每个拆分后的序列中的数字从小到大排序。然后你需要输出这些序列,其中字典序小的序列需要优先输出。

2.输入输出

Input

第一行为一个整数n。

Output

若干数的加法式子。

3.测试样例

Sample Input

7

Sample Output

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<=n<=8

二、源码实现

#include<iostream>
#include<cstdio>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
//创建一个动态数组a,a的默认初值为0
vector<int> a;
//定义整型变量n
int n;
//dfs 深度优先搜索
void dfs(int x,int sum)
{
	//这些自然数的和如果等于n的值 则输出这个序列
	if(sum==n)
	{
		cout<<a[0];
		for(int i=1;i<a.size();i++)
		{
			cout<<"+"<<a[i];
		}
		cout<<endl;
		return ;
	}
	//如果不等于,继续寻找+递归
	for(int i=x;i+sum<=n&&i!=n;i++)
	{
		a.push_back(i);
		dfs(i,sum+i);
		a.pop_back();
	}
}

int main()
{
	cin>>n;
	//调用dfs 通过深度优先搜索方法来寻找这些序列并输出
	dfs(1,0);
	return 0;
}

★关于DFS深度优先搜索算法
咱们可以从它的名字出发去理解:
①深度:这个算法可以理解为从树的顶点出发,逐层深入的遍历树的结点是不断向下的
②优先搜索:这个可以理解为我们按照选优条件去搜索符合条件的情况符合条件就继续向下搜索不符合回溯到初始状态


补充两点:
1️⃣DFS使用的数据结构stack 栈,空间复杂度为o(n);
2️⃣DFS中最重要的算法思想回溯和剪枝。另外DFS不具有最短性
其一:回溯是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。
另一就是:剪枝,就是减小搜索树规模、尽早排除搜索树中不必要的分支的一种手段。形象地看,就好像剪掉了搜索树的枝条,故称之为“剪枝”。

三、测试结果

7
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

--------------------------------
Process exited after 1.726 seconds with return value 0
请按任意键继续. . .

Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder)
如果对大家有帮助的话,希望大家能多多点赞+关注!这样我动力会更足哦! ღ( ´・ᴗ・` )比心

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Code_流苏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值