搜索入门练习题4 数的拆分 题解

题目描述

任何一个大于 \(1\) 的自然数 \(n\) ,总可以拆分成若干个小于 \(n\) 的自然数之和。当 \(n = 4\) 时,总共有 \(4\) 种拆分方法:

  • \(4=1+1+1+1\)
  • \(4=1+1+2\)
  • \(4=1+3\)
  • \(4=2+2\)

现在给你一个数 \(n(1 \le n \le 20)\) ,请按顺序输出 \(n\) 的所有拆分方案。

输入格式

输入包含一个整数 \(n(1 \le n \le 20)\) 。

输出格式

输出 \(n\) 的所有拆分方案,每种方案占一行,输出格式见样例输出。

样例输入

4

样例输出

4=1+1+1+1
4=1+1+2
4=1+3
4=2+2

题目分析

首先我们分析一下,因为 \(n \le 20\) 所以 \(n\) 最多也只能拆分成 \(n\) 个数之和,所以我开一个大小比 \(20\) 大一点的数组 ans[22] 就可以存放所有的加数了。
然后我再开一个函数 void f(int id, int tmp) 用来存放 ans[] 数组的第 id 个值,而这里的 tmp 用于表示我目前还剩下的可以用的数。比如,我调用了 f(3, 5),然后我将 ans[3] 设为了 2 (此时我将第 \(3\) 个加数设为了 \(2\) ),那我接下来就递归调用 f(4, 3) 了。因为我用掉了 \(5\) 里面的 \(2\) , 所以我剩下来的可以用的数就只剩下了 \(5-2=3\) 了。
然后我们再来看一下 f(id, tmp) ,表示我要在第 id 个位置选一个数放,但是这个数的范围是有限制的,假设我要在第 \(id\) 个位置放一个数 \(i\) ,那么这个 \(i\) 是有范围限制的,它需要满足一定的条件:

  • 当 \(id>1\) 时,必须满足 \(i \ge ans[id-1]\) ,因为公式里面的每一个加数都必须大于等于前一个加数;
  • 除非第 \(id\) 个位置的数是最后一个数(即将 \(i\) 作为 \(ans[id]\)),否则,为了满足 \(i\) 小于等于下一个加数的条件,必须使条件 \(i \le tmp-i\) (即 \(i \le \lfloor \cfrac n2 \rfloor\) )满足。
  • 当 \(id = 1\) 时,为了满足至少有两个加数的条件,必须满足 \(1 \le i \le \lfloor \cfrac n2 \rfloor\) 。

据此,我们可以编写深度优先搜索代码如下:

#include <bits/stdc++.h>
using namespace std;
int n, ans[22];
void f(int id, int tmp) {   // 当前放第id个数,剩余和为tmp
    if (id == 1) {  // id==1时,i从1到tmp/2
        for (int i = 1; i <= tmp/2; i ++) {
            ans[id] = i;        // 将ans[id]设为i
            f(id+1, tmp-i);     // 然后进下一层搜索
        }
    }
    else {  // id>1时,i从ans[id-1]到tmp/2
        for (int i = ans[id-1]; i <= tmp/2; i ++) {
            ans[id] = i;
            f(id+1, tmp-i);
        }
        // id>1时可将tmp设为ans[id],并输出方案
        ans[id] = tmp;
        cout << n << "=";
        for (int i = 1; i <= id; i ++) {
            cout << (i > 1 ? "+" : "") << ans[i];
        }
        cout << endl;
    }
}
int main() {
    cin >> n;
    f(1, n);    // 表示选第一个数的时候剩余数值为n
    return 0;
}

原文地址:https://www.cnblogs.com/zifeiynoip/p/11450703.html

时间: 2024-07-30 16:36:06

搜索入门练习题4 数的拆分 题解的相关文章

搜索入门练习题5 八皇后问题 题解

题目来源:<信息学奥赛一本通>例5.4 题目描述 要在国际象棋棋盘(\(8 \times 8\) 的棋盘)中放 \(8\) 个皇后,使任意两个皇后都不能互相吃.(提示:皇后能吃同一行.同一列.同一对角线的任意棋子.) 输出格式 输出一个整数,用于表示八皇后问题的放置方案. 题目分析 首先我们用 \((x,y)\) 来表示棋盘上第 \(x\) 行第 \(y\) 列的格子的坐标. 那么,两个皇后 \((x_1,y_1)\) 和 \((x_2,y_2)\) 会互相攻击当且仅当满足如下条件之一: 在同

搜索入门练习题7 最高效益和 题解

题目出处:<信息学奥赛一本通>例5.6 题目描述 设有A.B.C.D.E五人从事J1.J2.J3.J4.J5五项工作,每人只能从事一项,他们的效益如下所示. ? J1 J2 J3 J4 J5 A 13 11 10 4 7 B 13 10 10 8 5 C 5 9 7 7 4 D 15 12 10 11 5 E 10 11 8 8 4 每人选择五项工作中的一项,在各种选择的组合中,找到效益最高的一组输出. 题目分析 这道题目其实就是"全排列"问题的变形题,我们可以使用深度优先

搜索入门练习题2 全排列 题解

题目出处:课程=>搜索1=>题目A 题目描述 给定一个正整数 \(n\) ,按照递增顺序打印数字 \(1\) 到 \(n\) 的所有排列. 输入格式 一个整数 \(n(1 \le n \le 7)\) . 输出格式 按照递增顺序输出 \(n\) 个数的所有排列,每行代表一组排列, \(n\) 个数两两之间有一个空格分隔. 样例输入 3 样例输出 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 问题分析 这是一道搜索的题目. 我们知道搜索就是状态到状态之间的转换,其本质是

搜索入门练习题3 全组合 题解

题目出处:<信息学奥赛一本通>例5.2. 题目描述 设有 \(n\) 个数的集合 \(\{1,2,...,n\}\) ,从中任意取出 \(r\) 个数进行排列 \((r \le n)\) ,试列出所有的排列. 输入格式 输入包含两个正数 \(n,r(1 \le r \le n \le 10)\) 输出格式 输出从 \(n\) 个数的集合中选出 \(r\) 个数的所有组合,每个组合方案占一行.对于每个组合,按照从小到大的顺序输出组合中的所有元素,两两之间有一个空格分隔. 样例输入 3 2 样例输

搜索入门练习题1 素数环 题解

题目出处:<信息学奥赛一本通>例5.1. 题目描述 素数环:从 \(1\) 到 \(n(2 \le n \le 20)\) 这 \(n\) 个数摆成一个环,要求相邻的两个数的和是一个素数. 输入格式 输入包含一个整数 \(n(2 \le n \le 20)\) . 输出格式 按字典序从小到大的顺序输出所有排列方案,每个排列方案占一行.每行的 \(n\) 个数之间由一个空格分隔. 样例输入 2 样例输出 1 2 2 1 问题分析 很明显,这是一道可以用搜索解决的问题,我们可以采用"回溯

数的拆分

题目:输入整数n,输出n的拆分方案,即n=S1+S2+S3+S4+S5......+Sk,且Sn<=S(n+abs(i))啊,按字典序输出. 数据输入: 一行一个整数n,1<=n<=20 数据输出: 所有拆分方案(见样例) 输入: 4 输出: 1+1+1+1 1+1+2 1+3 2+2 4 total=5 题解: 五的拆分如下 1+1+1+1+1 1+1+1+2 1+2+2 1+4 5 可以发现有 "___"的部分是4的拆分 可以枚举一个i,拆分i和n-i,完成搜索,

搜索入门之dfs--经典的迷宫问题解析

今天来谈一下dfs的入门,以前看到的dfs入门,那真的是入门吗,都是把dfs的实现步骤往那一贴,看完是知道dfs的步骤了,但是对于代码实现还是没有概念.今天准备写点自己的心得,真的是字面意思--入门. DFS,即深度优先搜索,是一种每次搜索都向尽可能深的地方去搜索,到达尽头时再回溯进行其他结点去搜索的搜索策略.形象的说,这是一种“不撞南墙不回头”的策略. 其实也就是遍历,只不过不像一个线性数组的遍历那么直观罢了.说到回溯,每次看到这个词我都得思考一会,到底是怎么用栈进行回溯的呢?今天实际操作了一

swift菜鸟入门视频教程-06-函数

本人自己录制的swift菜鸟入门,欢迎大家拍砖,有什么问题可以在这里留言. 主要内容: 函数定义与调用(Defining and Calling Functions) 函数参数与返回值(Function Parameters and Return Values) 函数参数名称(Function Parameter Names) 函数类型(Function Types) 函数嵌套(Nested Functions) 视频地址: 百度网盘:http://pan.baidu.com/s/1dD8E5M

搜索:A - Tempter of the Bone题解

问题描述: The doggie found a bone in an ancient maze, which fascinated him a lot. However, when he picked it up, the maze began to shake, and the doggie could feel the ground sinking. He realized that the bone was a trap, and he tried desperately to get