自然数拆分问题:

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


输入:

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


代码:

#include<bits/stdc++.h>
using namespace std;
vector<int> vi = {1};
int n;
void backtracking(int m) {for (int i = vi[vi.size() - 1]; i <= m; i++) {vi.push_back(i);m -= i;if (m == 0) {cout << n << "=";for (int j = 1; j < vi.size()-1; j++)cout << vi[j] << "+";cout << vi[vi.size() - 1] << endl;}elsebacktracking(m);m += i;vi.pop_back();}
}
int main() {int m;cin >> n;m = n;backtracking(m);return 0;
}

思路分析:

zdm老师讲课的方式着实不顾及我这种脑子笨的人,导致回溯法讲完了我也没弄明白什么是回溯思想,太致命了啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊aaaaaaa一段代码看了一周(根本没思路)
言归正传,慢慢磨还是能磨出来的,要不然这篇文也不会问世了,经过对递归进行人脑分析,慢慢的,剪枝的概念变得清晰了,尝试着写了一下,再改了改,就成功了。

将一个自然数分解,在不知道回溯的方法之前,我想到了一种“沉降”的方式,比如5一开始分解为1,1,1,1,1,可以每次把第一个1“尽可能”向后移动,这个尽可能意为不能出现前面的数比后面的大的情况,举个例子,1,1,1,2就是把第一个1移动到最后一个1上面,两个1就合为2了,把整串数字立起来,就是每次把最上面的那个数字“尽可能”下降,可以把数字大小理解为平台宽度,大平台不能落在小平台上面,所以要“尽可能”沉降。这种方法无论是时间复杂度还是空间复杂度都严重超标,不过依旧不失为一种清奇的思路,说不定什么时候就用到了。

来,轮到回溯了。回溯就是先往前试探,当试探到错误结果的时候,再回退一步或者若干步,选择新的路径继续试探,向前试探的方式就是递归,递归返回就是回溯。是不是想到了深度优先遍历,其实回溯和深度优先遍历很像,那么深度优先遍历是如何防止多次进入同一个节点的呢,做标记,回溯法同样也不应该多次进入同一个节点,回溯法的“做标记”操作更为粗暴------剪枝。毫无疑问,剪枝操作将会是回溯算法的核心,当这条路走不通的时候,我就不必再考虑它了。整体思路有了,我们来进入这道题的思路。

接下来是对整个程序思路的完整解释,会有很多重复的地方,理解能力不强可以看完,如果脑袋灵光基本上看几行就可以去理解代码了。

一个自然数,拿5来举例,先将它分解为1+1+1+1+1,到此我们得到了第一个解,此时已经到达了分解的尽头,我们将最后一个加上的1再减去,回溯一次,这时候5 = 1+1+1+1,余1,这个1作为一个范围而言是从1到1,只有一个选择,而且这个选择我们一开始就已经选择过了,回溯第二次,5 = 1+1+1,余2,这个2作为范围而言是从1到2,1这个分支我们已经考虑过了,接下来考虑2这个分支,5=1+1+1+2,余0,这时候我们得到了第二个解,此时分解已经走到了尽头,回溯一次,5=1+1+1,余2,这个2作为范围而言是从1到2,而1和2这两个分支我们都已经考虑过了,回溯第二次,5=1+1,余3,3作为范围而言是从1到3,1这个分支我们已经考虑过了,接下来考虑2,5=1+1+2,余1,这时候,即使把剩下的1加到尾部形成5=1+1+2+1,这个组合在以前已经出现过了(在判断的时候,我们不必检索以前出现过的组合是否有重复的,我们只需要保证组合里面的数是非降序排列的就可以了),而且剩下的是一个1,1作为范围只是从1到1,所以当5=1+1,余3的时候,考虑2这个分支是不可能得到结果的,接下来我们考虑3分支,5=1+1+3,余0,我们得到了第三个解,这时候,分解又到了尽头,该干什么了,回溯,回溯一次,5=1+1,余3,这个3作为范围而言是1到3,1到3的分支我们都已经尝试过了,回溯第二次,5=1,余4,接下来从1到4继续进行考虑,1已经考虑过了,选择2分支,5=1+2,余2,2作为范围而言是1到2,考虑1,5=1+2+1,余1,不满足条件,回溯,选择2,5=1+2+2,余0,这时候我们得到了第四个解,分解到达尽头,回溯一次,5=1+2,余2,2作为范围而言,从1到2我们都已经选择过了,回溯第二次,5=1,余4,我们之前已经选择到2了,接下来选择3分支,5=1+3,余1,这时候只能把1加上去,5=1+3+1不满足条件,回溯,选择4分支,5=1+4,余0,这时候我们得到第五个解,分解到达尽头,回溯第一次,5=1,余4,1到4我们都已经考虑过了,回溯第二次,5=,余5,5作为范围而言是1到5,1我们已经考虑过了,接下来考虑2,5=2,余3,3作为范围而言是从1到3,我们选择1,会发现5=2+1,余2不符合条件,回溯,选择2,5=2+2,余1依旧不符合条件,回溯,选择3,5=2+3,余0,这时候我们得到了第六个解,分解到达尽头,回溯一次,5=2,余3,123我们都已经选择过了,回溯第二次,5=,余5,我们已经选择了2,接下来选择3,5=3,余2,这时候我们可以选择1和2,可无论选哪个都不满足条件,回溯,5=,余5,选择4,5=4,余1,选择1不符合条件,回溯,5=,余5,选择5,5=5,余0,这时候我们得到了第七个解,分解到达尽头,回溯,5=,余5,分支5我们已经考虑过了,至此所有的分支我们都已经考虑过了,递归至此也就结束了,数一数刚好七个解,按格式输出就可以了。

如果还是不明白可以试着以树的形式画一下,思路一下子就清晰了

自然数分解(罗列出一个自然数的加数的所有组合)(回溯)相关推荐

  1. 自然数分解:任何一个自然数m的立方均可写成m个连续奇数之和。编程实现:输入一自然数 n,求组成 n3的 n个连续奇数。

    标题 自然数分解 类别 流程控制 时间限制 2S 内存限制 1000Kb 问题描述 任何一个自然数m的立方均可写成m个连续奇数之和.例如: 13=1 23=3+5 33=7+9+11 43=13+15 ...

  2. 快速找出一个自然数的所有因数的方法

    1.分解质因数. 例如:24的质因数有:2.2.2.3,那么,24的因数就有:1.2.3.4.6.8.12.24. 2.找配对. 例如:24=1*24.2*12.3*8.4*6,那么,24的因数就有: ...

  3. 【C语言】从键盘输入一个自然数n,再输入n个自然数,求出这n个自然数的最大值max和最小值min

    如下 //从键盘输入一个自然数n,再输入n个自然数,求出这n个自然数的最大值max和最小值min #include <stdio.h> #define N 10 int main() {i ...

  4. 编写一个递归算法,找出从自然数1,2,3,…,n中任取r个数的所有组合。例如n=5,r=3时所有组合为543,542,541,532,531,521,432,431,421,321。

    编写一个递归算法,找出从自然数1,2,3,-,n中任取r个数的所有组合.例如n=5,r=3时所有组合为543,542,541,532,531,521,432,431,421,321. 若设这n个自然数 ...

  5. 读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字。

    读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式:每个测试输入包含1个测试用例,即给出自然数n的值.这里保证n小于2^64. 输出格式:在一行内输出n的各位数字之和的每一 ...

  6. C语言解决读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字。

    /* 读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式:每个测试输入包含1个测试用例,即给出自然数n的值.这里保证n小于10100. 输出格式:在一行内输出n的各位数字之 ...

  7. 1002 写出这个数 (20)(20 分) 读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字。 输入格式:每个测试输入包含1个测试用例,即给出自然数n的值。这里保证n小于10^10

    https://pintia.cn/problem-sets/994805260223102976/problems/994805324509200384 1002 写出这个数 (20)(20 分) ...

  8. 11091 最优自然数分解问题

    问题描述: 设n是一个正整数. (1)现在将n分解为若干个互不相同的自然数之和,且使这些自然数的乘积最大. (2)现在将n分解为若干个自然数之和,且使这些自然数的乘积最大. 编程任务:对于给定的正整数 ...

  9. Python实现大自然数分解为最多4个平方数之和(1)

    问题描述:任意大自然数,总是能分解为最多4个平方数的和,所谓平方数是指它是一个自然数的平方.例如:72884 = 4^2 + 138^2 + 232^2,33788 = 1^2 + 3^2 + 17^ ...

最新文章

  1. 100行代码,使用 Pygame 制作一个贪吃蛇小游戏!
  2. 一群参与境内外赌博网站的开发的程序员被抓,网友:切勿面向监狱编程...
  3. 春节必看的五个Asp.net源码!
  4. 应用宝认领应用签名_腾讯应用宝认领应用步骤
  5. 乐视网:对FF与第九城市设立合资公司的计划不知情
  6. linux服务器如何添加sudo用户
  7. 微软物联网平台再推新!
  8. 使用/调用 函数的时候, 前面加不加 对象或 this?
  9. c语言file_C语言程序的编译和调试
  10. table里面用三目_三个方法快速找到SAP后台Table
  11. GUI界面设计1 三角函数
  12. 各大网络安全厂商及安全产品
  13. 微信小程地图片未加载成功的情况 Failed to load local image resource
  14. iPad远程控制windows主机及内网穿透原理
  15. 【附资料】PMP证书有用吗?
  16. 混合波束成形| MIMO系统的DFT码本
  17. Redis 中哨兵sentinel 机制、从宕机及恢复、主库宕机及恢复解决方案
  18. 电阻 电容 并联电路
  19. 一些linux常用操作(1)
  20. NB-IoT贴片式SIM卡引脚定义和尺寸

热门文章

  1. 手机智能控制汽车系统作用详解
  2. 大象转身 | 沃尔玛搅局社区团购
  3. docker启动容器发生Error response from daemon故障
  4. 解决:ERROR kuhl m_privilege simple: Rtiadjustprivilege (20) c0000061
  5. 使用C++,用四阶Runge-Kutta的方法来求解一阶常微分方程
  6. 2017身残志坚的定西考生魏祥上清华
  7. 河南省历年高考人数(2004-2021)
  8. 光遇脚本弹琴_光遇自动弹琴脚本手机版
  9. 武汉星起航跨境——中东电商蓬勃发展,亚马逊中东站点如何发货?
  10. 计算机网络基础——WWW万维网