news 2026/4/26 17:30:55

5.回溯算法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
5.回溯算法

装载问题:

问题描述:

有一批共n个集装箱要装上载重量为c的轮船,其中集装箱i重量为wi,集装箱装载问题要求确定在不超过轮船载重量的前提下,将尽可能多的集装箱装上轮船,且集装箱的重量之和最大

回溯算法实现:

#include<iostream> using namespace std; #define NUM 1000 int n; int c; int w[NUM]; int x[NUM]; int r; int cw; int bestw; int bestx[NUM]; void Backtrack(int t) { if(t>n) { if(cw>bestw) { for(int i=1; i<=n; i++) bestx[i] = x[i]; bestw = cw; } return; } r -= w[t]; if(cw+w[t]<=c) { x[t] = 1; cw += w[t]; Backtrack(t+1); cw -= w[t]; } if(cw+r>bestw) { x[t]=0; Backtrack(t+1); } r += w[t]; } int main() { while (scanf("%d%d", &c, &n)!=EOF) { r = 0; for(int i=1;i<=n;i++) { scanf("%d", &w[i]); r += w[i]; } cw = 0; bestw = 0; Backtrack(1); printf("%d\n", bestw); for(int i=1;i<=n;i++) if (bestx[i]) printf("%d ", i); printf("\n"); } }

0-1背包问题:

#include<iostream> using namespace std; #define NUM 100 int c; int n; int cw; int cv; int bestv; struct Object{ int w; int v; double d; }Q[NUM]; bool cmp(Object a, Object b) { if(a.d>=b.d) return true; else return false; } int Bound(int i) { int cleft = c-cw; int b = cv; while (i<n && Q[i].w<=cleft) { cleft -= Q[i].w; b += Q[i].v; i++; } if (i<n) b += cleft*Q[i].d; return b; } void backtrack(int i) { if (i+1>n) {bestv = cv; return;} if (cw+Q[i].w<=c) { cw += Q[i].w; cv += Q[i].v; backtrack(i+1); cw -= Q[i].w; cv -= Q[i].v; } if (Bound(i+1)>bestv) backtrack(i+1); } int main() { while(scanf("%d",&c) && c) { cw = 0; cv = 0; bestv = 0; scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%d%d",&Q[i].w,&Q[i].v); Q[i].d = 1.0*Q[i].v/Q[i].w; } sort(Q, Q+n, cmp); backtrack(0); printf("%d\n", bestv); } return 0; }

图的m着色问题:

#include <iostream> using namespace std; #define NUM 100 int n; int m; int a[NUM][NUM]; int x[NUM]; int sum ; bool Same(int t) { int i; for(i=1; i<=n; i++ ) if( (a[t][i] == 1) && (x[i] == x[t]) ) return false; return true; } void BackTrack(int t ) { int i; if( t > n ) { sum ++ ; for(i=1; i<=n ;i++) printf("%d ",x[i]); printf("\n") ; } else for(i=1; i<=m; i++ ) { x[t] = i; if( Same(t) ) BackTrack(t+1); x[t] = 0; } } int main() { scanf("%d %d",&n,&m); memset(a,0,sizeof(a)); int b ,e ; while(scanf("%d%d",&b,&e) && (b||e) ) { a[b][e] = 1 ; a[e][b] = 1 ; } sum = 0; BackTrack(1); printf("Total=%d\n",sum ) ; return 0; }

n皇后问题:

在 N×N 的国际象棋棋盘上放置 N 个皇后,使得任意两个皇后不能处于同一行、同一列或同一对角线上(即彼此无法相互攻击)。‌‌

输入为n

输出为所有可能的放置情况,最后一行是方案总数,第一个数字代表第一列放置的行数,依次类推

#include <iostream> #include <cmath> using namespace std; #define NUM 20 int n; int x[NUM]; int sum; inline bool Place(int t) { int i; for (i=1; i<t; i++) if ((abs(t-i) == abs(x[i]-x[t])) || (x[i] == x[t])) return false; return true; } void Backtrack(int t) { int i; if (t>n) { sum++; for (i=1; i<=n; i++) printf(" %d", x[i]); printf("\n"); } else for (i=1; i<=n; i++) { x[t] = i; if (Place(t)) Backtrack(t+1); } } int main() { while (cin>>n) { sum = 0; Backtrack(1); printf("Total= %d\n\n", sum); } return 0; }

旅行商问题:

#include <iostream> using namespace std; #define NUM 100 int n; int m; int a[NUM][NUM]; int x[NUM]; int bestx[NUM]; int cc; int bestc; int NoEdge = -1; void Backtrack(int t) { if(t==n) { if(a[x[n-1]][x[n]]!= NoEdge && a[x[n]][1]!= NoEdge && (cc + a[x[n-1]][x[n]]+a[x[n]][1]<bestc||bestc== NoEdge)) { for(int i=1; i<=n; i++) bestx[i] = x[i]; bestc = cc + a[x[n-1]][x[n]] + a[x[n]][1]; } return; } else { for(int i=t; i<=n; i++) { if(a[x[t-1]][x[i]]!= NoEdge && (cc + a[x[t-1]][x[i]]< bestc||bestc == NoEdge)) { swap(x[t],x[i]); cc += a[x[t-1]][x[t]]; Backtrack(t+1); cc -= a[x[t-1]][x[t]]; swap(x[t],x[i]); } } } } int main() { int i, j; int from, to, length; while (scanf("%d%d", &n, &m) && n) { for (i=0; i<NUM; i++) for (j=1; j<NUM; j++) a[i][j] = NoEdge; for (i=0; i<m; i++) { scanf("%d%d%d", &from, &to, &length); a[from][to] = length; a[to][from] = length; } bestc = NoEdge; for(i=1; i<=n; i++) x[i] = i; Backtrack(2); for(j=1; j<=n; j++) printf("%d ", bestx[j]); printf("\n%d\n", bestc); } return 0; }

流水作业调度问题:

#include <iostream> using namespace std; #define NUM 20 #define infinite 10000 int n; int job[NUM][3]; int x[NUM]; int bestx[NUM]; int f1; int f2[NUM]; int f; int bestf; void Backtrack(int t) { if (t>n) { bestf = f; for (int i=1; i<=n; i++) bestx[i]=x[i]; return; } for (int i=t; i<=n; i++) { f1 += job[x[i]][1]; f2[t] = ((f2[t-1]>f1) ? f2[t-1] : f1)+job[x[i]][2]; f += f2[t]; if (f<bestf) { swap(x[t], x[i]); Backtrack(t+1); swap(x[t], x[i]); } f1 -= job[x[i]][1]; f -= f2[t]; } } int main() { int i; while (cin>>n) { memset(bestx, 0, sizeof(bestx)); memset(f2, 0, sizeof(f2)); for (i=1; i<=n; i++) scanf("%d%d", &job[i][1], &job[i][2]); bestf = infinite; f1 = 0; f = 0; for (i=0; i<=n; i++) x[i] = i; Backtrack(1); cout<<bestf<<endl; } }

子集和问题:

#include<iostream> using namespace std; #define NUM 10000 int n; int c; int cw; int bestw; int w[NUM]; int x[NUM]; int r; bool flag; void backtrack(int t) { if(t>n) { if(cw==c) { for(int i=1; i<=n; i++) if (x[i]) printf("%d ",w[i]); printf("\n"); flag = false; } return; } r -= w[t]; if (cw+w[t]<=c) { x[t] = 1; cw += w[t]; backtrack(t+1); cw -= w[t]; } if (cw+r>bestw) { x[t] = 0; backtrack(t+1); } r += w[t]; } int main() { while(scanf("%d%d",&n,&c) && (n||c)) { r = 0; for(int i=1; i<=n; i++) { scanf("%d", &w[i]); r += w[i]; } cw = 0; bestw = 0; flag = true; backtrack(1); if (flag) printf("No Solution!\n"); } return 0; }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/25 7:00:32

什么是云原生

云原生是一种现代化的软件开发和部署方法&#xff0c;旨在充分利用云计算的优势&#xff0c;提高应用程序的可伸缩性、弹性和可靠性。 云原生的详细定义包括云原生计算基金会&#xff08;Cloud Native Computing Foundation&#xff0c;CNCF&#xff09;的官方定义和延伸含义。…

作者头像 李华
网站建设 2026/4/25 23:20:10

如何在Kafka中使用SSL/TLS证书认证

在 Kafka 中配置 SSL/TLS 证书认证&#xff08;核心是双向认证&#xff0c;客户端验证 broker、broker 验证客户端&#xff09;需完成证书准备、Broker 配置、客户端配置三大核心步骤&#xff0c;以下是详细实操指南&#xff08;基于 Kafka 2.8&#xff0c;JKS 格式证书&#x…

作者头像 李华
网站建设 2026/4/23 8:38:10

最新网络安全行业入门全指南:前景、方向与实战学习路径

最新网络安全行业入门全指南&#xff1a;前景、方向与实战学习路径 在数据即资产的今天&#xff0c;网络安全早已不是黑客攻防的小众领域 ——2025 年国内网络安全人才缺口突破350万&#xff0c;渗透测试、安全研发等岗位起薪比普通 IT 岗位高 20%&#xff0c;3 年经验工程师年…

作者头像 李华
网站建设 2026/4/23 16:46:27

AI 如何改变 IT 行业:从工具到伙伴的深刻变革

引言 在过去的几年里,人工智能(AI)已经从科幻概念迅速演变为 IT 行业的核心驱动力。2025 年,我们看到 AI 不再是锦上添花的功能,而是深度融入开发、运维、安全、数据等几乎所有领域的底层技术。AI 的广泛应用正在重塑 IT 从业者的日常工作,既带来了效率的飞跃,也改变了…

作者头像 李华