P2404 自然数的拆分问题

自然数的拆分问题

题目描述

任何一个大于 1 1 1 的自然数 n n n,总可以拆分成若干个小于 n n n 的自然数之和。现在给你一个自然数 n n n,要求你求出 n 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 ≤ n ≤ 8 1\le n\le 8 1n8

解析

这道题我实在是不想多说,因为已经做过两个同类题目了,而且我都在CSDN上发布过比较详细的解析。如果想看的话就点击这些蓝色的文字去看那些文章的解析部分吧!

【算法1-3】暴力枚举——组合的输出

【算法1-3】暴力枚举——PERKET

有趣的是,那两个题的标签是“暴力枚举”,而这道题目的标签是“搜索”。那我还是简单提两句,详细的解说请点击那两串蓝色的汉字。

对于任何一个要输入的n,一定是从1开始地毯式搜索。设置递归dfs,传入参数k表示当前找到了k个数(用来输出)。用数组记录第k个元素取的是几,数组每一项不能小于前一项。sum累加求和,注意动态加减。递归的出口是sum==n或者sum>n

AC代码如下:

#include
using namespace std;
const int N=12;
int n,sum,a[N];
void dfs(int k)
{
	if(sum>n) return;
	if(sum==n)
	{
		for(int i=1;i<k-1;i++)
		 cout<<a[i]<<"+";
		cout<<a[k-1]<<endl;
		return;
	}
	for(int i=a[k-1];i<n;i++)
	{
		a[k]=i;
		sum+=a[k];
		dfs(k+1);
		sum-=a[k];
	}
}
int main()
{
	cin>>n;
	a[0]=1;
	dfs(1);
}

举一反三。

你可能感兴趣的:(洛谷,深度优先,算法,c++)