文章目录

  • 回溯算法模板
    • 递归回溯
    • 迭代回溯
    • 子集树
    • 排列树
  • 题目
    • 拔河问题
    • 旅行商问题
    • 连续邮资问题

回溯算法模板

递归回溯

回溯法对解空间做深度有限搜索,因此在一般情况下可用递归函数来实现回溯法如下:

模板:

void backtrace(int t){if(t>n)output(x);else{for(int i=f(n,t);i<=g(n,t);i++){x[t]=i;if(constraint(t)&&bound(t)){backtrace(t+1);}}}
}

迭代回溯

采用树的非递归深度优先遍历算法,也可将回溯法便是为一个非递归的迭代过程如下:

模板:

void backtrace(int t){if(t>n){output();}while(t<n){if(f(n,t)<=g(n,t)){for(int i=f(n,t);i<=g(n,t);i++){x[t]=h(i);if(constraint(t)&&bound(t)){output(x);}elset++;}}else{t--;}}
}

子集树

模板:

void backtrace(int t){if(t>n){output();}else{for(int i=0;i<=1;i++){x[t]=i;if(constraint(t)&&bound(t)){backtrace(t+1);}}}
}

排列树

模板:

void backtrace(int t){if(t>n){output();}else{for(int i=t;i<=n;i++){swap(x[i],x[t]);if(constraint(t)&&bound(t)){backtrace(t+1);}swap(x[i],x[t]);}}
}

题目

拔河问题

#include<iostream>using namespace std;#define N 100int w[N],n,totalw,tempw,temp_person_num,x[N];void swap(int *a,int *b){int temp=*a;*a=*b;*b=temp;
}//12
//48 43 57 64 50 52 18 34 39 56 16 75void backtrace(int k){int i;if(k>n/2){if(tempw==totalw/2){//            cout<<"tempw="<<tempw<<endl;for(i=1;i<=n/2;i++){cout<<x[i]<<" ";}cout<<endl;}}else{for(i=k;i<=n;i++){swap(&x[k],&x[i]);tempw+=x[k];
//            for(int j=1;j<=n;j++){//                cout<<x[j]<<" ";
//            }
//            cout<<endl;
//            cout<<"tempw=="<<tempw<<endl;if(tempw<=totalw/2){backtrace(k+1);}tempw=tempw-x[k];swap(&x[k],&x[i]);}}
}int main(){int i;//拔河总人数cin>>n;//初始化装入对象for(i=1;i<=n;i++){cin>>x[i];totalw+=x[i];}backtrace(1);return 0;
}

旅行商问题

#include<iostream>
using namespace std;
#define MAX 1000
int g[100][100], x[100], bestx[100];int cl = 0, bestl = MAX, n;void Traveling(int t) {int j;if (t > n) { //到达叶子结点if (g[x[n]][1] != -1 && (cl + g[x[n]][1] < bestl)) { //推销员到的最后一个城市与出发的城市之间有路径,且当前总距离比当前最优值小for (j = 1; j <= n; j++)bestx[j] = x[j];bestl = cl + g[x[n]][1];}} else { //没有到达叶子结点for (j = t; j <= n; j++) { //搜索扩展结点的左右分支,即所有与当前所在城市临近的城市if (g[x[t - 1]][x[j]] != -1 && (cl + g[x[t - 1]][x[j]] < bestl)) { //若果第t-1个城市与第t个城市之间有路径且可以得到更短的路线swap(x[t], x[j]);    //保存要去的第t个城市到x[t]中cl += g[x[t - 1]][x[t]]; //路线长度增加Traveling(t + 1);    //搜索下一个城市cl -= g[x[t - 1]][x[t]];swap(x[t], x[j]);}}}
}
int main() {int i, j;cin >> n;for (i = 1; i <= n; i++)for (j = 1; j <= n; j++)cin >> g[i][j];for (i = 1; i <= n; i++) {x[i] = i;bestx[i] = 0;}Traveling(2);cout << "城市路线:" << endl;for (i = 1; i <= n; i++)cout << bestx[i] << ' ';cout << bestx[1];cout << endl;cout << "最短路线长度:" << endl;cout << bestl << endl;return 0;
}

连续邮资问题

#include <stdio.h>
#include<malloc.h>#define MAX_NM 10
#define MAX_POSTAGE 1024
#define INF 2147483647int n, m;
int x[MAX_NM], ans[MAX_NM], y[MAX_POSTAGE],  maxStamp, r;/** backtrack(i)表示x[0...i-1]这i张邮票已经完全确定,* 相应于x[0...i-1]的最大连续邮资区间r和每种邮资所需要的* 最少邮票张数y[0...r]也都确定,现在枚举x[i]* 的每个值,确定x[i]*/void backtrack(int i) {int *backup_y, backup_r;int next, postage, num, tmp;if(i >= n) {if(r > maxStamp) {maxStamp = r;for(tmp = 0; tmp < n; tmp++)ans[tmp] = x[tmp];}return;}//临时的存储贴出某价值邮票所需的邮票数 backup_y = (int*)malloc(MAX_POSTAGE * sizeof(int));for(tmp = 0; tmp < MAX_POSTAGE; tmp++)backup_y[tmp] = y[tmp];//临时的最大邮资区间 backup_r = r;//下一个票数的区间应该是大于x[i-1]并且小于等于当前的最大邮资区间+1,因为如果定义r+2作为下一个,那么r+1就会空出来 for(next = x[i - 1] + 1; next <= r + 1; next++) {/* update x[i] *///第i个位置的邮资 x[i] = next;/* update y */for(postage = 0; postage < x[i-1] * m; postage++) {if(y[postage] >= m)continue;for(num = 1; num <= m - y[postage]; num++)if(y[postage] + num< y[postage + num * next]   //y[postage]是不能是inf && (postage + num * next< MAX_POSTAGE)) //下标不要越界了 y[postage + num * next] = y[postage] + num;}/* update r */while(y[r + 1] < INF) r++;backtrack(i + 1);/* restore */r = backup_r;for(tmp = 0; tmp < MAX_POSTAGE; tmp++) y[tmp] = backup_y[tmp];}free(backup_y);
}int main() {int i;sscanf("%d%d", &n, &m);x[0] = 1;//r的定义为最大邮资区间,每一个都是1就是最大的范围了。 r = m;  //当前情况下贴出某邮资需要的最少邮票数,y[i]=i. for(i = 0; i <= r; i++) y[i] = i;while(i < MAX_POSTAGE) y[i++] = INF;//记录最后的最大邮资区间 maxStamp= 0;backtrack(1);printf("max stamp is: %d\n", maxStamp);for(i = 0; i < n; i++) printf("%4d", ans[i]);return 0;
}

回溯算法,模板,拔河,旅行商,连续邮资问题题解相关推荐

  1. 力扣刷题-python-回溯算法-1(回溯算法模板、题型)

    文章目录 1.回溯算法 2.回溯算法模板 3.回溯实例(77.216.17.39.40.131.93.78.90.491.46.47) 4.总结 1.回溯算法 回溯算法的本质就是穷举,最多再加上剪枝, ...

  2. 鲸鱼优化算法WOA求解旅行商TSP优化问题(2022.6.2)

    鲸鱼优化算法WOA求解旅行商TSP优化问题(2022.6.2) 引言 1.鲸鱼优化算法WOA 1.1 WOA算法原理介绍 1.1.1 包围猎物 1.1.2 气泡网式攻击猎物(开发阶段) 1.1.3 寻 ...

  3. 回溯算法模板之:332. 重新安排行程

    题目链接:332.重新安排行程 分析:需要重新排列行程,并且需要按照自然排序的大小,所以第一步就先进行字典的创建,key是起始地,value是可到达所有的目的地,然后对value进行排序.使用回溯算法 ...

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

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

  5. Nuist集训队作业:深度优先搜索(回溯算法)

    Nuist集训队第一次作业:深度优先搜索(回溯算法) 引例 深搜基本思想及回溯算法模板 P1706 全排列问题 P1219 八皇后 P1605 迷宫 P1101 单词方阵 小结 引例 国际西洋棋棋手马 ...

  6. 数字拆分问题算法回溯_回溯算法:求子集问题!

    给「代码随想录」一个星标吧! ❝ 认识本质之后,这就是一道模板题 通知:我将公众号文章和学习相关的资料整理到了Github :https://github.com/youngyangyang04/le ...

  7. 回溯算法团灭子集、排列、组合问题

    回溯算法团灭子集.排列.组合问题 一.子集 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集). 说明:解集不能包含重复的子集. 示例: 输入: nums = [1,2,3] ...

  8. 回溯算法——复原IP地址(Leetcode 93)

    题目选自Leetcode 93.复原IP地址 由于我们需要找出所有可能复原出的 IP 地址,因此可以考虑使用回溯的方法,对所有可能的字符串分隔方式进行搜索,并筛选出满足要求的作为答案. 通俗来讲,就是 ...

  9. 算法训练Day24 | 回溯算法理论基础;LeetCode77.组合(经典的回溯问题)

    目录 回溯算法理论基础 1. 什么是回溯法 2. 回溯法的效率 3. 回溯法解决的问题 4. 如何理解回溯法 5. 回溯法模板-- 回溯三部曲 6. 总结 LeetCode77.组合 1. 思路 2. ...

最新文章

  1. 读javascript高级程序设计03-函数表达式、闭包、私有变量
  2. 实践教程|YOLOX目标检测ncnn实现
  3. pgsql 相关的命令
  4. 换个姿势学数学:二次函数与拆弹部队
  5. BZOJ5323 洛谷4562:[JXOI2018]游戏——题解
  6. 数据为什么要可视化?如何可视化?
  7. 在阿里做博士后是一种怎样的体验?
  8. php 连接数据库 pod,PHP PDO类解决数据库连接问题
  9. git submodule使用
  10. 利用模板模式重构JDBC操作
  11. python自动化运维书籍推荐_《Python 自动化运维:技术与最佳实践》
  12. Java中java.lang.Class的初步学习
  13. sql server 别名_SQL Server别名概述
  14. 人工智能时代!Python跃升编程语言第一名!
  15. KEIL识别不出野火STM32仿真器问题解决
  16. 【MySQL】根据数据表中日期字段查询某个月每一天的数据量?查询数据表中所有日期每天的数据量?近三天每天数据量?
  17. A40I构建编译应用程序的SDK环境
  18. MySQL--管理数据库表相关操作
  19. 【笔记】微信小程序基础
  20. Android eSIM-LPA基于Android13的实现

热门文章

  1. Linux如何创建文件在指定的目录?
  2. MySQL 数据库备份一键执行脚本 --- 全库备份和增量备份
  3. Nginx显示500错误原因和解决方法
  4. linux 我的世界 跨平台联机,《我的世界》将支持跨平台联机
  5. javaweb总结——孤傲苍狼
  6. java中admin什么意思_Spring Boot Admin 的使用详解
  7. 怎么确定电磁波的相位
  8. 王者荣耀新24赛季服务器维护,《王者荣耀》s24赛季改动内容分享 s24新赛季更新公告...
  9. Python金融大数据分析——第9章 数学工具 笔记
  10. 记录vue中使用scss报红但是不影响css样式,代码行会提示css-rcurlyexpected这个问题