回溯法的设计思想:

回溯法从根节点出发,按照深度优先策略遍历解空间树,搜索满足约束条件的解。在搜索至树中任一节点时,先判断该节点对应的部分解是否满足约束条件I,是否超出目标函数的界,也就是判断该节点是否包含问题的最优解,如果肯定不包含,则跳过对以该节点为根的子树的搜索(即所谓剪枝),返回上一层的节点,从其他子节点寻找通向最优解的路径;否则,进入以该节点为根的子树,继续按照深度优先策略搜索。
回溯法的搜索过程涉及的节点称为搜索空间,只是整个解空间树的一部分,在搜索过程中,通常采用两种策略避免无效搜索:

  • 用约束条件剪去得不到可行解的子树
  • 用目标函数剪去得不到最优解的子树
    这两类函数统称剪枝函数。

需要注意的是:
问题的解空间树是虚拟的,并不需要在算法运行时构造一棵真正的树结构,只需要存储从根节点到当前节点的路径。

连续邮资问题

问题描述:

假设某国家发行了n种不同面值的邮票,并且规定每张信封上最多只允许贴m张邮票。连续邮资问题要求对于给定的n和m,给出邮票面值的最佳设计,在1张信封上贴出从邮资1开始,增量为1的最大连续邮资区间。 例如当n=5,m=4时,面值为1,3,11,15,32的5种邮票可以贴出邮资的最大连续区间是1到70。

输入样例:

5 4
1 3 11 15 32

输出样例:

70

算法思路:

参考:https://www.jianshu.com/p/313d1e98c0d7

每张信封最多贴m张邮票,也就是说可能贴了m张,也可能贴了0张、1张等等。为了便于计算,我们可以把未贴满m张邮票看作贴了x张邮票和m-x张面值为0的邮票,从而构造一棵完全多叉树。若求所有可能的组合情况,解空间是(n+1)^m。
以n=5,m=4为例,解空间为完全多叉树,图中只以一条路径为例:

实际求解需要对其进行剪枝:解的约束条件是必须满足当前解的邮资可以构成增量为1的连续空间,所以在搜索至树中任一节点时,先判断该节点对应的部分解是否满足约束条件,也就是判断该节点是否包含问题的最优解,如果肯定不包含,则跳过对以该节点为根的子树的搜索,返回上一层的节点,从其他子节点寻找通向最优解的路径;否则,进入以该节点为根的子树,继续按照深度优先策略搜索。
求解过程:

  1. 读入邮票面值数n,每张信封最多贴的邮票数m
  2. 读入邮票面值数组nums[],除了正常面值,再加入一个值为0的面值
  3. 循环求取区间最大值maxValue,maxValue初始设为0
    ① 从0张邮票开始搜索解空间,如果当前未达到叶节点,且过程值temp=temp+nums[i]未达到当前记录的区间最大值maxValue,则继续向下搜索
    ② 若超过了区间最大值maxValue,则当前面值不是可行解,计算下一个面值nums[i+1]。若循环结束,当前节点的所有面值都无法满足,则说明再往下搜索也不可能有可行解,这个时候回溯到上一节点
    ③ 若当前已搜索到叶节点,判断当前路径下的解temp是否满足比当前记录的区间最大值maxValue大1。若满足,则更新区间最大值maxValue;若不满足,回溯到上一节点
  4. 重复步骤3直到没有满足当前区间最大值maxValue+1的可行解,则当前记录的maxValue就是区间最大值

算法实现:

public class Main {// n表示邮票面值数,m表示每张信封最多贴的邮票数private static int n;private static int m;// 邮票面值数组private static int[] nums;// 当前解是否可行private static boolean accFlag;// 记录区间最大值private static int maxValue = 0;// 搜索过程中的邮资private static int temp = 0;public static void main(String[] args) {// 读取键盘输入Scanner sc = new Scanner(System.in);while (true) {n = sc.nextInt();m = sc.nextInt();// 多一个是假设有面值为0的邮票nums = new int[n + 1];nums[0] = 0;for (int i = 1; i < n + 1; i++) {nums[i] = sc.nextInt();}solution(n, m, nums);System.out.println("maxValue=" + maxValue);}}public static void solution(int n, int m, int[] nums) {// 求解区间最大值,一直搜索,直到确定最大值while (true) {accFlag = false;// 每次都从0张邮票开始搜索解空间// 当前求解的目标是判断是否存在比当前区间最大值大1的解search(0);// 若存在if (accFlag) {// 连续区间增量加1maxValue++;} else {break;}}}/*** 搜索解空间,找到比当前区间最大值大1的解** @param t 当前邮票数量*/public static void search(int t) {// 叶节点,结束搜索if (t == m) {// 当前解可以将连续区间最大值加1if (temp == maxValue + 1) {accFlag = true;}// 此时已经是叶节点,若不是可行解,则需要回溯到t-1return;}// 未结束,继续向下搜索// 遍历所有面值for (int i = 0; i < nums.length; i++) {temp += nums[i];// 如果当前未达到叶节点,且过程值未达到当前记录的区间最大值,则继续向下搜索if (temp <= maxValue + 1) {search(t + 1);}// 若超过了区间最大值,则当前面值不是可行解,需要回溯,计算下一个面值temp -= nums[i];}}
}

运行结果

连续邮资问题-回溯法相关推荐

  1. 算法设计与分析第5章 回溯法(二)【回溯法应用】

    第5章 回溯法 5.2 应用范例 1.0-1背包问题 有n件物品和一个容量为c的背包.第i件物品的重量是w[i],价值是p[i].求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和 ...

  2. 5.12回溯法--连续邮资问题--子集树

    回溯法的题目太多了,不想写这个代码了,于是我就开始水一篇文章,就单纯的分析一下这个问题保持整本书完整的队形 问题描述 如何用有限的邮票数,贴出更多面额的需求? 举例 n=5,m=4 设计1:X1={1 ...

  3. 回溯算法,模板,拔河,旅行商,连续邮资问题题解

    文章目录 回溯算法模板 递归回溯 迭代回溯 子集树 排列树 题目 拔河问题 旅行商问题 连续邮资问题 回溯算法模板 递归回溯 回溯法对解空间做深度有限搜索,因此在一般情况下可用递归函数来实现回溯法如下 ...

  4. 连续邮资问题的回溯法解决办法

    /* 连续邮资问题 算法设计: 该问题是设计最佳的邮票面值,用来表示最大的区间 对于连续邮姿问题,用n元组x[1:n]表示n种不同的邮票面值并约定它们从小到大排列. 整数r表示当前使用不超过m张邮票能 ...

  5. 回溯法求解连续邮资问题

    实验内容与要求 内容:假设某国家发行了n中不同面值的邮票,并且规定每张信封上最多只允许贴m张. 要求:对于给定的m和n的值,给出邮票面值的最佳设计,使得可以在一张信封上贴出从邮资1开始,增量为1的最大 ...

  6. 算法:连续邮资问题(回溯+动态规划+剪枝)

    问题描述 假设国家发行了n种不同面值的邮票,并且规定每张信封上最多只允许m张邮票.连续邮资问题要求对于给定的n和m的值,给出邮票面值的最佳设计,即在1张信封上可贴出从邮资1开始,增量为1的最大连续邮资 ...

  7. 回溯法 -数据结构与算法

    1.回溯法算法思想: 定义: 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术 ...

  8. LeetCode Gray Code(回溯法)

    问题:gray code是一种二进制数字系统,两个连续的数只有一位不同.给出一个正整数n,n表示gray code的位数,输出gray code. 思路:使用回溯法.通过枚举0,1,2,3的gray ...

  9. POJ1256 Anagram(回溯法)

    题意: 输出字符串中字符的所有排列方式 要点: 回溯法可以将每种情况遍历一遍(注意跳过连续的相同的字符),重点在于排序,先排序再回溯可以保证输出按照字典序,但这题的排序不太一样:'A'<'a'& ...

最新文章

  1. Linux bash管道符“|”使用介绍与例子
  2. 植树节准备中:合种樟子松、华山松和云杉
  3. python查看安装包的版本scipy,numpy,matplotlib等
  4. Python3.7环境配置
  5. SQLServer2008 Transact_SQL语言基础实例
  6. 元素的样式设置 元素类样式的操作 开关灯效果 获取兄弟元素 当前元素的兄弟元素样式
  7. 【解题报告】Leecode911. 在线选举——Leecode每日一题系列
  8. 清华大学-美团数字生活联合研究院成立
  9. 在mysql数据库中,多表查询,事务,DCL,
  10. 邪恶改装:TPYBoard制作廉价WIFI干扰器
  11. html换浏览器div的位置固定不变,浏览器窗口更改时,HTML div不在适当的位置
  12. CodeBlocks中文乱码
  13. 光滑噪声数据常用的方法_数据挖掘部分课后习题
  14. TI-C2000-捕获模块ECAP应用-以欧姆龙E6B2-CWZ6C测速编码器为例
  15. 分子动力学模拟之周期性边界处理
  16. android studio多媒体播放器,Android支持全屏、小窗口的视频播放器
  17. C++11 右值引用和移动语义
  18. 哈希表(HashMap)的学习与实现
  19. 2018.8.18日,直播笔记
  20. JAVA毕业设计Web网上购书后台管理系统计算机源码+lw文档+系统+调试部署+数据库

热门文章

  1. 什么是代理服务器?它有哪些分类?
  2. AI绘画发展史(伪):从免费到吃屎;YSDA·自然语言处理课程8K Star;伯克利CS285·深度强化学习课程;前沿论文 | ShowMeAI资讯日报
  3. Aspose使用方法
  4. Project——唇部试妆
  5. 两化融合贯标之-波特五力分析
  6. 跟杨春娟学SpringMVC笔记:Form表单之Spring验证框架
  7. ReleaseMutex函数
  8. java metro 下载_JavaFX Metro UI 和 开发库使用简介
  9. 正在配置您的计算机,解决方案:Win10系统正在配置Windows Update并停留在100%,如何解决...
  10. C语言详解系列——分支语句详解if、switch