回溯法求解连续邮资问题
实验内容与要求
内容:假设某国家发行了n中不同面值的邮票,并且规定每张信封上最多只允许贴m张。
要求:对于给定的m和n的值,给出邮票面值的最佳设计,使得可以在一张信封上贴出从邮资1开始,增量为1的最大连续邮资区间。
实验分析
①对于连续邮资的问题,由于实验开始是仅给出面值的数量,而面值的具体值是未知的。但是由于邮资需要从1开始,因此,面值具体值中必然有1。可以考虑建立一个数组用于存储具体的面值。X[1:n]表示从小到大存储具体面值。
②当面值为1时,可形成的连续邮资区间为1~m,在此基础上,若要增加面值,为保证区间连续,第二个面值必然要在2~m+1中取(第二个面值不能为1,并且若为m+2或者更大时,只用一个就变为m+2,此时不连续),第三个面值则需要根据前两个面值能达到的最大值来确定。第i个面值x[i]的连续区间若为1~r时,则第x[i+1]的个的取值必然为x[i]+1到r+1。则从第一个面值开始,接下来的各个面值的取值都由上一个面值以及能形成的最大值来取。
③但是为了求解最大连续区间,需要将面值的所有情况进行考虑,则对面值可能取值的语法树进行递归遍历,即回溯。递归到叶子节点时,将当前情况的最大值进行记录并与之前的进行比较,若更大则保存最大值,之后回溯到上一层继续求解,直到将所有情况计算完成。
④为在第n层得到最大连续邮资区间,则在前几层进行计算是,必须要达到即保证连续,又要保证每个邮资值尽量使用比较少的邮票张数,即多使用邮资大的邮票。这就要求每引进一个新的邮票的时候,需要对当前邮资值数组进行更新,以保证每个邮资值的达到使用的是最少的邮票数。
代码
#include<stdio.h>
#define maxl 1000 //表示最大连续值
#define maxint 32767
int n,m; //n为邮票种类数,m为能贴的最大张数
int maxvalue; //表示最大连续值
int bestx[100]; //表示最优解
int y[maxl]; //y[k],存储表示到k值,所使用的最少邮票数
int x[100]; //存储当前解
void backtrace(int i,int r);int main(){printf("请输入邮票面值数:");scanf("%d",&n);printf("请输入能张贴邮票的最大张数:");scanf("%d",&m);for(int i=0;i<=n;i++){x[i]=0;bestx[i]=0;} for(int i=0;i<maxl;i++){y[i]=maxint;}x[1]=1;y[0]=0;maxvalue=0;backtrace(1,0);printf("当前最优解为:");for(int i=1;i<=n;i++){printf("%d ",bestx[i]);} printf("\n最大邮资为:");printf("%d",maxvalue);return 1;
} void backtrace(int i,int r){for(int j=0;j<=x[i-1]*m;j++){ //对上一层的邮资值数组进行更新,上限是x[i-1]*m if(y[j]<m){for(int k=1;k<=m-y[j];k++){ //从只使用一个x[i]到使用m-y[i]个,即使用最多的最大值,降低邮票数 if(y[j]+k<y[j+x[i]*k]){y[j+x[i]*k]=y[j]+k; //如果前面的某一个情况加上k个x[i],所达到邮资值使用的邮票数少于原来的邮票数则更新 }}}}while(y[r]<maxint){ //向后寻找最大邮资值 r++;}if(i==n){ //i=n表示到达叶子节点。 if(r-1>maxvalue){ //若大于最大值,则更新最优值与最优解 for(int k=1;k<=n;k++){bestx[k]=x[k]; }maxvalue = r-1;}return;}int z[maxl];for(int k=0;k<maxl;k++){ //由于每一层需要对多种情况进行运算,因此需要将上一层的邮资值数组保留 z[k] = y[k];}for(int j=x[i]+1;j<=r;j++){ //对下一层进行运算 x[i+1]=j;backtrace(i+1,r-1);for(int k=0;k<maxl;k++)y[k]=z[k];}
}
回溯法求解连续邮资问题相关推荐
- LeetCode之单词搜索(回溯法求解)
题目 给定一个 m x n 二维字符网格 board 和一个字符串单词 word .如果 word 存在于网格中,返回 true :否则,返回 false . 单词必须按照字母顺序,通过相邻的单元格内 ...
- 回溯法求解N皇后问题(Java实现)
回溯法:也称为试探法,它并不考虑问题规模的大小,而是从问题的最明显的最小规模开始逐步求解出可能的答案,并以此慢慢地扩大问题规模,迭代地逼近最终问题的解.这种迭代类似于穷举并且是试探性的,因为当目前的可 ...
- 【算法分析】实验 4. 回溯法求解0-1背包等问题
目录 实验内容 实验目的 实验结果 步骤1:描述与分析 步骤2:策略以及数据结构 步骤3 步骤4 步骤5 步骤6 实验总结 实验内容 本实验要求基于算法设计与分析的一般过程(即待求解问题的描述.算法设 ...
- php生成迷宫图片,PHP实现基于回溯法求解迷宫问题的方法详解
本文实例讲述了PHP实现基于回溯法求解迷宫问题的方法.分享给大家供大家参考,具体如下: 引言 最近在leetcode上看了些算法题,有些看着很简单的很常用的东西,竟然一下子想不出来怎么求解,比如说:实 ...
- 回溯法求解图着色问题
回溯法求解图着色问题 #include <iostream> #include <cstdlib> using namespace std; #define n 5 #defi ...
- 回溯法求解N皇后问题及其时间复杂度分析
回溯法求解N皇后问题及其时间复杂度分析 一.回溯法简介 1. 什么是回溯法? 2. 回溯法的时间复杂度分析 蒙特卡罗方法 蒙特卡罗方法在回溯法求解时间复杂度中的应用 二.回溯法求解N皇后问题 1. 回 ...
- 算法设计与分析 实验三 回溯法求解地图填色问题
回溯法求解地图填色问题 一.实验目的与要求 1.实验基本要求: 2.实验亮点: 二.实验内容与方法 三.实验步骤与过程 1.未优化的回溯: (1)算法描述: (2)编程实现 (3)运行并测试: 2.对 ...
- 回溯法求解0-1背包问题
回溯法求解0-1背包问题时比较随机序列和按 v/w 降序排列的算法 问题描述: 针对0-1背包问题,尝试用回溯法. 物品总数N=10,背包容量 C=26, 物品的重量数组为w={7,3,10,12,1 ...
- 回溯法 | 求解装载问题
问题描述: 有 n 个集装箱要装上一艘载重量为 W 的轮船,其中集装箱 i (1<=i<=n) 的重量,为wi.子啊装在体积不受限制的情况下,将尽可能重的集装箱装上轮船,当重量相同时要求选 ...
最新文章
- vmware添加新硬盘 挂载新硬盘 硬盘扩容
- 4000字,25张精美交互图表,开启Plotly Express之旅!
- 如何动态的向数组中插入键值对_在Java中实现的一个简单“HashMap”
- 异步api_如何设计无服务器异步API
- 骨牌覆盖问题 KxM
- 有关i++问题,和一些另外的易错点
- 循环神经网络系列(二) LSTM 和 GRU
- 理解numpy dot函数
- 对向量求导的常用公式
- 在论文中如何设置页眉页脚
- 调整HTML5画布中图像的大小
- 几何矩的物理意义,由Camshift算法引起
- 遇到Process finished with exit code -1073740791 (0xC0000409)实在不能解决的时候要注意
- HttpWebRequest 无法连接到远程服务器
- SpringBoot2核心技术最好的一篇文章——2. 核心技术
- 需求与商业模式创新-需求8-面谈
- 2022-ISCC信息安全与对抗竞赛wp-misc(详解,有脚本( •̀ ω •́ )y)
- 小linux软件下载,超小的Linux发行版Puppy Linux 8.0发布下载
- 修改本地host文件加入可用ip使谷歌浏览器翻译插件重新生效
- linux上的一个玩具
热门文章
- Zotero使用教程
- The History of Tcl/Tk
- github.com/gin-contrib/sessions教程
- 【UE4笔记】C++游戏控制的摄像机
- 《测试开发方法论》导读
- 配置计算机卡住了一直0,win10更新卡在0%怎么办_win10更新一直0%的两种解决方法...
- c# textBox中只能输入数字及ABCDEF六个大写字母,小写字母自动转换为大写字母
- blender学习记录 —— 广为人知的甜甜圈教程
- 阿里云CA证书pem格式转换cer格式
- 详解Active Directory域搭建