7-7 自然数拆分问题 (60 分)

一个整数N(N > 1)可以拆分成若干个大于等于1的自然数之和,请你输出所有不重复的拆分方式。

若满足集合A=B,则称这两种拆分方式是重复的。

例如 6 = 3 + 2 和 6 = 2 + 3, 就是重复的拆分方式。

输入格式:
一个正整数N(1≤N≤52)。

注意:本题N的上限52,是经过PTA平台服务器测试后得到的上限,能够保证较好的搜索策略在PTA提交,在1s内求解。本地PC机上,即使较好方法运行时间也可能大于1s,如果觉得方法没问题,可以先提交试试。

输出格式:
按照拆分方案的字典序由小大到大,输出所有方案,请参考输出样例

输入样例:
在这里给出一组输入。例如:

6

结尾无空行
输出样例:
在这里给出相应的输出。例如:

6=1+1+1+1+1+1
6=1+1+1+1+2
6=1+1+1+3
6=1+1+2+2
6=1+1+4
6=1+2+3
6=1+5
6=2+2+2
6=2+4
6=3+3
6=6

结尾无空行

  • 知识点: dfs,暴力,回溯,剪枝。

思路:

  • 用dfs进行搜索,判定条件sum=n,这里要用vector
    进行存储,方便输出和回溯。

  • 进行深搜时要升序进行搜索(不降序)因此dfs(sum,prenum)要有一个当前数的参数。

  • 下一次进行搜索时i要从prenum开始。

自我纠正:

  • 当找到sum==n时sum不需要归零,vector也不需要清零,但是在搜索时要进行回溯方便下一次寻找。

源码:

#include<bits/stdc++.h>
using namespace std;
int n;
vector<int> v;
vector<int> ::iterator it;
void dfs(int sum, int prenum) {
	if (sum >= n) {
		if (sum > n) {
			//sum = 0;
			//v.clear();
			return;
		}
		cout << n << "=";
		for (it = v.begin();it != v.end();it++) {
			if (it != --v.end())
				cout << *it << "+";
			else
				cout << *it << endl;
		}
		//sum = 0;
		//v.clear();
		return;
	}
	for (int i = prenum;sum + i <= n;i++) {
		v.push_back(i);
		dfs(sum + i, i);
		v.pop_back();
	}

}
int main() {
	
	cin >> n;
	dfs(0, 1);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值