算法分析与设计编程题 贪心算法

活动安排问题

题目描述

在这里插入图片描述
在这里插入图片描述

解题代码

vector<bool> greedySelector(vector<vector<int>>& intervals) {int n = intervals.size();// 将活动区间按结束时间的从小到大排序auto cmp = [](vector<int>& interval1, vector<int>& interval2) {return interval1[1] < interval2[1];};sort(intervals.begin(), intervals.end(), cmp);vector<bool> res(n, false);// 结束时间最早的活动必定位于某个最优解之中int minStart = intervals[0][1];res[0] = true;for (int i = 1; i < n; ++i) {if (intervals[i][0] >= minStart) { // 将不重叠的活动加入最优解集res[i] = true;minStart = intervals[i][1];}}return res;
}

最优装载

题目描述

在这里插入图片描述

解题代码

vector<bool> optimisedLoading(vector<int>& weight, int c) {int n = weight.size();vector<bool> select(n, false);// 定义一个小顶优先队列,使得对于i,若其weight[i]最小,则排在队列的队头priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;for (int i = 0; i < n; ++i) {// 构建二元组<重量,下标>并放入优先队列q.emplace(weight[i], i);}for (int i = 0; i < n; ++i) {auto [w, idx] = q.top(); // (C++17语法)取队头元素的w和对应下标q.pop();if (c < w) break; // 无法继续装载select[idx] = true; // 选择装载该货物c -= w; // 剩余载货量减少}return select;
}

哈夫曼编码

题目描述

在这里插入图片描述
在这里插入图片描述

解题代码

struct HuffmanNode {int left, right; // 左右结点int parent; // 父结点int weight; // 权重char data; // 数据HuffmanNode(int left = -1, int right = -1, int parent = -1, int weight = 0, char data = '*'): left(left), right(right), parent(parent), weight(weight), data(data) {}
};vector<HuffmanNode> createHuffmanTree(vector<int>& weight, vector<char>& data) {int n = weight.size();vector<HuffmanNode> huffmanTree(2 * n);// 定义一个小顶优先队列,使得对于i,若其weight[i]最小,则排在队列的队头priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;for (int i = 0; i < n; ++i) { // 初始化哈夫曼树和优先队列huffmanTree[i].data = data[i];huffmanTree[i].weight = weight[i];q.emplace(weight[i], i);}for (int i = 0; i < n - 1; ++i) {auto [weight1, idx1] = q.top(); // 取权值最小结点q.pop();auto [weight2, idx2] = q.top(); // 取权值第二小结点q.pop();// 创建两结点的父结点,其下标为n+ihuffmanTree[idx1].parent = n + i;huffmanTree[idx2].parent = n + i;// 初始化该父结点的相关信息huffmanTree[n + i].left = idx1;huffmanTree[n + i].right = idx2;huffmanTree[n + i].weight = weight1 + weight2;// 将该父结点的<权值,下标>加入优先队列,以便进行贪心选择q.emplace(weight1 + weight2, n + i);}return huffmanTree;
}void printHuffmanCode(vector<HuffmanNode>& huffmanTree) {stack<int> s;for (int i = 0; i < huffmanTree.size() / 2; ++i) {int cur = i; // 当前结点下标int pre = huffmanTree[cur].parent; // 当前结点的父结点的下标while (pre != -1) {if (huffmanTree[pre].left == cur) {s.emplace(0); // 当前结点为其父结点的左孩子}else {s.emplace(1); // 当前结点为其父结点的右孩子}// 轮换下标cur = pre;pre = huffmanTree[cur].parent;}// 打印相应的哈夫曼编码cout << huffmanTree[i].data << " ";while (!s.empty()) {cout << s.top();s.pop();}cout << endl;}
}

单源最短路径

题目描述

在这里插入图片描述

解题代码

图的定义

struct MGraph {vector<char> vertices; // 顶点数组vector<vector<int>> edges; // 邻接矩阵
};

BellmanFord

此算法可适用于含有负权值边的图。

// G:图	start:源点	dist:最短路径
bool BellmanFord(MGraph& G, int start, vector<int>& dist) {int n = G.vertices.size();// 初始化最短路径dist.assign(n, INT32_MAX);for (int j = 0; j < n; ++j) {dist[j] = G.edges[start][j];}for (int t = 0; t < n - 1; ++t) { // 松弛次数tfor (int i = 0; i < n; ++i) { // 边的起点ifor (int j = 0; j < n; ++j) { // 边的终点jif (G.edges[i][j] != INT32_MAX && dist[i] != INT32_MAX&& dist[i] + G.edges[i][j] < dist[j]) {dist[j] = dist[i] + G.edges[i][j]; // 松弛操作}}}}for (int i = 0; i < n; ++i) {for (int j = 0; j < n; ++j) {// 若执行完算法后仍然存在非最短路径,则该图存在权值为负的环路,无最短路径if (G.edges[i][j] != INT32_MAX && dist[i] != INT32_MAX&& dist[i] + G.edges[i][j] < dist[j]) {return false;}}}return true;
}

Dijkstra

本算法仅适用于所有边的权值均为正的图。

// G:图	start:源点	dist:最短路径
void Dijkstra(MGraph& G, int start, vector<int>& dist) {int n = G.vertices.size();// 初始化最短路径dist.assign(n, INT32_MAX);vector<int> pre(n, -1); // 前驱数组vector<bool> visited(n, false); // 访问集,表示对应顶点最短路径是否已经找到visited[start] = true;// 小顶优先队列,元素为<dist[j],j>priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;// 初始化最短路径for (int j = 0; j < n; ++j) {dist[j] = G.edges[start][j];q.emplace(dist[j], j);}while (!q.empty()) {int i = q.top().second; // 贪心选择最近结点iq.pop();visited[i] = true; // 结点i最短路径已得到for (int j = 0; j < n; ++j) { // 利用结点i进行松弛操作if (visited[j]) continue; // 结点j已得到最短路径,无需松弛if (G.edges[i][j] != INT32_MAX && dist[i] != INT32_MAX&& dist[i] + G.edges[i][j] < dist[j]) {dist[j] = dist[i] + G.edges[i][j]; // 松弛操作pre[j] = i; // 更新前驱结点q.emplace(dist[j], j); // 加入优先队列}}}// 打印源点到各结点的最短路径stack<int> s;for (int i = 0; i < n; ++i) {if (i == start) continue;if (dist[i] == INT32_MAX) {cout << "inf" << ": " << G.vertices[start] << "->" << G.vertices[i] << endl;}else {cout << dist[i] << ": " << G.vertices[start] << "->";int x = pre[i];while (x != -1) {s.emplace(x);x = pre[x];}while (!s.empty()) {cout << G.vertices[s.top()] << "->";s.pop();}cout << G.vertices[i] << endl;}}
}

最小生成树

题目描述

在这里插入图片描述

解题代码

Kruskal

void Kruskal(MGraph& G) {int n = G.vertices.size();// 边集,元素为<权值weight,起点u,终点v>vector<tuple<int, int, int>> edges;for (int i = 0; i < n; ++i) {for (int j = i + 1; j < n; ++j) {if (G.edges[i][j] != INT32_MAX) {// 将边加入边集edges.emplace_back(G.edges[i][j], i, j);}}}// 对边集按权值大小进行升序排序sort(edges.begin(), edges.end());// 简单并查集,father[x]存放x的父结点vector<int> father(n);// 寻找x所在集合的父结点(所在连通分量编号)auto findFather = [&](int x) {int f = father[x];while (f != x) {x = f;f = father[x];}return f;};for (int i = 0; i < n; ++i) {father[i] = i; // 初始父结点为自身}int cnt = 0; // 已找到的边个数for (int i = 0; cnt <= n - 1 && i < edges.size(); ++i) {auto [weight, u, v] = edges[i];int fu = findFather(u);int fv = findFather(v);// 若u和v父结点相同(即u和v位于一个连通分量中),若选择加入边uv,则会导致回路if (fu != fv) { cout << G.vertices[u] << " - " << G.vertices[v] << " : " << weight << endl;father[fu] = fv; // 两个连通分量合并为一个++cnt;}}
}

Prim

void Prim(MGraph& G) {int n = G.vertices.size();// minDist[i]表示结点i距离MST最近距离vector<int> minDist(n, INT32_MAX);// connected[i]表示在MST中与结点i相连的结点vector<int> connected(n, 0);// 表示结点i是否已加入MSTvector<bool> visited(n, false);visited[0] = true;for (int j = 1; j < n; ++j) {// 初始化最近距离minDist[j] = G.edges[0][j];}for (int i = 1; i < n; ++i) {// 寻找距离MST的最近结点kint minVal = INT32_MAX, k = -1;for (int j = 1; j < n; ++j) {if (!visited[j] && minDist[j] < minVal) {minVal = minDist[j];k = j;}}if (k == -1) break;// 将结点k加入MST中visited[k] = true;cout << G.vertices[connected[k]] << " - " << G.vertices[k] << " : " << minVal << endl;// 更新minDist数组和connected数组for (int j = 1; j < n; ++j) {if (!visited[j] && G.edges[k][j] < minDist[j]) {minDist[j] = G.edges[k][j];connected[j] = k;}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/108792.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【LeetCode-中等题】78. 子集

文章目录 组合并集问题汇总&#xff1a;题目方法一&#xff1a;动态规划方法二&#xff1a;递归加回溯(关键----startIndex) 组合并集问题汇总&#xff1a; 1、子集去重版本 2、组合非去重版本 3、组合去重版本 题目 注意&#xff1a;这里的nums数组里面的元素是各不相同的&a…

SpringBoot2.0(Lombok,SpringBoot统一返回封装)

目录 一&#xff0c;Lombok简介二&#xff0c;添加依赖三&#xff0c;Springboot统一返回封装3.1&#xff0c;创建一个工具包util和一个JsonData类 四&#xff0c;示例实体类五&#xff0c;Data注解 一&#xff0c;Lombok简介 ​ java工程中&#xff0c;我们要创建很多的java B…

SpringCloud(17~21章):Alibaba入门简介、Nacos服务注册和配置中心、Sentinel实现熔断与限流、Seata处理分布式事务

17 SpringCloud Alibaba入门简介 17.1 why会出现SpringCloud alibaba Spring Cloud Netflix项目进入维护模式 https://spring.io/blog/2018/12/12/spring-cloud-greenwich-rc1-available-now 说明 Spring Cloud Netflix Projects Entering Maintenance Mode 什么是维护模…

【GO语言基础】前言

系列文章目录 【Go语言学习】ide安装与配置 【GO语言基础】前言 【GO语言基础】变量常量 【GO语言基础】数据类型 文章目录 系列文章目录一、基础知识包和函数函数声明语法简洁性 括号成对出现GO常用DOS命令命名规则项目目录结构注释 总结 一、基础知识 包和函数 //声明本代…

记一次线程堵塞(挂起)导致消息队列积压

1 背景 A服务作为生产者&#xff0c;每天发送上千万的mq消息&#xff0c;每一个消息包含500个用户ids数据。B服务作为消费者&#xff0c;接受MQ消息并通过http调用第三方请求进行业务处理&#xff0c;消费组启用了rabbitmq的多线程消费组&#xff0c;一个实例并发40个mq消费者…

企业如何高效平滑迁移数据?火山引擎DataLeap上线整库搬迁解决方案

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 近日&#xff0c;火山引擎大数据研发治理套件DataLeap上线整库搬迁解决方案&#xff0c;包括整库离线同步、整库实时同步两大能力&#xff0c;大大提升数据上云便捷…

C++项目实战——基于多设计模式下的同步异步日志系统-⑤-实用工具类设计

文章目录 专栏导读获取系统时间time介绍 getTime函数设计判断文件是否存在stat介绍exists函数设计 获取文件所在路径find_last_of介绍path函数设计 创建文件所在目录mkdir介绍find_first_of介绍函数createDirectory设计 实用工具类整理 专栏导读 &#x1f338;作者简介&#xf…

图论第三天|130. 被围绕的区域、417. 太平洋大西洋水流问题、827. 最大人工岛

130. 被围绕的区域 文档讲解 &#xff1a;代码随想录 - 130. 被围绕的区域 状态&#xff1a;开始学习。 思路&#xff1a; 步骤一&#xff1a; 深搜或者广搜将地图周边的 ‘O’ 全部改成 ’A’&#xff0c;如图所示&#xff1a; 步骤二&#xff1a; 再遍历地图&#xff0c;将 …

(3)MyBatis-Plus待开发

常用注解 TableName MyBatis-Plus在确定操作的表时&#xff0c;由BaseMapper的泛型决定即实体类型决定&#xff0c;且默认操作的表名和实体类型的类名一致,如果不一致则会因找不到表报异常 //向表中插入一条数据 Test public void testInsert(){User user new User(null, &…

基因型数据VCF转EXCEL亲测好用

import pandas as pd df pd.read_csv(shuju.vcf, sep\t, comment#, headerNone,encodingutf-8) df.to_excel(outputFile2.xlsx, indexFalse,encodingutf-8) 以上就是转成功的截图&#xff0c;需要注意的是一定要写入编码方式&#xff0c;UTF-8 &#xff0c;第一次我没有写编码…

Zabbix“专家坐诊”第203期问答汇总

问题一 Q&#xff1a;用的模板&#xff0c;没用创建动作&#xff0c;但是触发器触发了我钉钉直接被通知了&#xff0c;怎么取消模板自带的动作&#xff1f; A&#xff1a;没有动作是不会触发事件告警的 &#xff0c;确定是从这个平台推出的钉钉消息&#xff1f;或者看下zabbix…

论文解读 | 用于3D对象检测的PV-RCNN网络原创

原创 | 文 BFT机器人 01 背景 本文的背景涉及到3D物体检测&#xff0c;这是一个在自动驾驶和机器人等领域应用广泛的重要问题。在这些领域&#xff0c;LiDAR传感器被广泛用于捕捉3D场景信息&#xff0c;生成不规则且稀疏的点云数据。这些点云数据提供了理解和感知3D场景的关键…