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

news2024/12/22 19:46:16

活动安排问题

题目描述

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

解题代码

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+i
		huffmanTree[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) { // 松弛次数t
		for (int i = 0; i < n; ++i) { // 边的起点i
			for (int j = 0; j < n; ++j) { // 边的终点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]; // 松弛操作
				}
			}
		}
	}
	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; // 贪心选择最近结点i
		q.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是否已加入MST
	vector<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的最近结点k
		int 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.coloradmin.cn/o/1010268.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(文末赠书)我为什么推荐应该人手一本《人月神话》

能点进来的朋友&#xff0c;说明你肯定是计算机工作的朋友或者对这本书正在仔细琢磨着的朋友。 文章目录 1、人人都会编程的时代&#xff0c;我们如何留存?2、小故事说明项目管理着为什么必看这本书3、如何评价《人月神话&#xff1a;纪念典藏版》4、本书的目录&#xff08;好…

模方新建工程时,显示空三与模型坐标系不一致怎么解决

答:检查空三xml与模型的metadata.xml的坐标系是否一致&#xff0c;metadata文件是否有在data目录外面。 模方是一款针对实景三维模型的冗余碎片、水面残缺、道路不平、标牌破损、纹理拉伸模糊等共性问题研发的实景三维模型修复编辑软件。模方4.0新增单体化建模模块&#xff0c;…

无人机+三维实景建模助力古建筑保护,传承历史记忆

历史文化建筑&#xff0c;承载着过去各个时代的文化记忆。无论是保存还是修缮古建筑&#xff0c;都需要将其基本信息进行数字化建档&#xff0c;为修缮提供精准参考。根据住建部的要求&#xff0c;从2020年开始到2022年&#xff0c;全国需完成历史建筑100%测绘及系统录入工作&a…

OPENCV实现人类识别(包括眼睛、鼻子、嘴巴)

人脸识别步骤 # -*- coding:utf-8 -*- """ 作者:794919561 日期:2023/9/14 """ import cv2 import numpy as np # load xml face_xml = cv2.CascadeClassifier(F:\\learnOpenCV\\opencv\\data\\haarcascades\\haarcascade_frontalface_defaul…

计算机提示vcomp120.dll丢失怎样修复,vcomp120.dll丢失的4个修复方法分享

随着科技的飞速发展&#xff0c;计算机已经成为了人们日常生活和工作中不可或缺的重要工具。在享受计算机带来的便利的同时&#xff0c;我们也会遇到各种各样的问题&#xff0c;其中计算机丢失vcomp120.dll文件就是一种常见的困扰。vcomp120.dll是 Visual C Redistributable 的…

【操作系统】聊聊协程为什么可以支撑高并发服务

在实际的业务开发中&#xff0c;比如针对一个业务流程&#xff0c;调用三方&#xff0c;然后存储数据&#xff0c;从oss上获取数据。其实都是进行的同步调用&#xff0c;说白了就是A完成之后&#xff0c;B在继续完成。如果整个过程中A、B、C 分别耗时100、300、200毫秒。那么整…

vue基础知识十:Vue中组件和插件有什么区别?

一、组件是什么 回顾以前对组件的定义&#xff1a; 组件就是把图形、非图形的各种逻辑均抽象为一个统一的概念&#xff08;组件&#xff09;来实现开发的模式&#xff0c;在Vue中每一个.vue文件都可以视为一个组件 组件的优势 降低整个系统的耦合度&#xff0c;在保持接口不…

【VSCode】自动生成Jupyter(ipynb)文件的目录

下载插件 一键生成 然后就出来咯&#xff5e;

关于HTTP协议的概述

HTTP 的报文大概分为三大部分。第一部分是请求行&#xff0c;第二部分是请求的首部&#xff0c;第三部分才是请求的正文实体。 POST 往往是用来创建一个资源的&#xff0c;而 PUT 往往是用来修改一个资源的。 Accept-Charset&#xff0c;表示客户端可以接受的字符集。防止传过…

Python工程师Java之路(p)Module和Package

文章目录 1、Python的Module和Package2、Java的Module和Package2.1、Module2.1.1、分模块开发意义2.1.2、模块的调用 2.2、Package Module通常译作模块&#xff0c;Package通常译作包 1、Python的Module和Package Python模块&#xff08;Module&#xff09;&#xff1a;1个以.…

模拟实现C语言--strlen函数

模拟实现C语言–strlen函数 模拟实现C语言--strlen函数一、strlen函数是什么&#xff1f;二、strlen函数的模拟实现2.1 计数器方式实现strlen函数2.2 不创建临时变量计数器方式实现strlen函数2.3 指针-指针方式实现strlen函数 三、strlen函数的返回类型 一、strlen函数是什么&a…

vue-esign 签字组件

1、安装 npm install vue-esign --save 2、引入 // main.js import vueEsign from vue-esign Vue.use(vueEsign) 3、参数 属性说明类型默认值width画布宽度&#xff0c;即导出图片的宽度Number800height画布高度&#xff0c;即导出图片的高度Number300lineWidth画笔粗细Nu…

C++多线程的用法(包含线程池小项目)

一些小tips: 编译命令如下&#xff1a; g 7.thread_pool.cpp -lpthread 查看运行时间&#xff1a; time ./a.out 获得本进程的进程id&#xff1a; this_thread::get_id() 需要引入的库函数有&#xff1a; #include<thread> // 引入线程库 #include<mutex> //…

【python环境搭建】一台电脑下安装不同python版本时如何安装模块

我的环境中安装了2个版本的python&#xff1a; 一个时Anaconda的 一个是python3.10 多个版本python的安装 卸载 pip使用 详细方法可以看这个贴子 Windows环境同时安装多个版本的Python解释器 pip的使用 安装package pip install [package] 更新package pip install [pack…

下属不服管,当众顶撞自己怎么办?

作为领导者&#xff0c;面对下属公然顶撞自己&#xff0c;是一种不尊重和不合适的行为&#xff0c;可能会让你感到失望和困惑。然而&#xff0c;在处理这一情况时&#xff0c;你可以采取以下措施来妥善处理&#xff1a; 保持冷静&#xff1a;尽管受到了侮辱和指责&#xff0c;…

怎么获取别人店铺的商品呢?

jd.item_search_shop(获得店铺的所有商品) 为了进行电商平台 的API开发&#xff0c;首先我们需要做下面几件事情。 1&#xff09;开发者注册一个账号 2&#xff09;然后为每个JD应用注册一个应用程序键&#xff08;App Key) 。 3&#xff09;下载JDAPI的SDK并掌握基本的API…

【脑机接口论文与代码】 基于自适应FBCCA的脑机接口控制机械臂

Brain-Controlled Robotic Arm Based on Adaptive FBCCA 基于自适应FBCCA的脑机接口控制机械臂论文下载&#xff1a;算法程序下载&#xff1a;摘要1 项目介绍2 方法2.1CCA算法2.2FBCCA 算法2.3自适应FBCCA算法 3数据获取4结果4.1脑地形图4.2频谱图4.3准确率 5结论 基于自适应FB…

【C++】常用算术生成算法

0.前言 1.accumulate #include <iostream> using namespace std;// 常用算术生成算法 #include<vector> #include<numeric> //accumulate 的调用头文件void test01() {vector<int>v;for (int i 0; i < 100; i){v.push_back(i);}int total accumu…

msvcp140.dll是什么东西,如何解决msvcp140.dll丢失的问题的方法分享

在现代生活中&#xff0c;电脑已经成为我们工作、学习和娱乐的重要工具。然而&#xff0c;电脑问题的出现往往会给我们的生活带来不便。其中&#xff0c;"msvcp140.dll丢失"是一个常见的电脑问题。本文将详细介绍这个问题的原因和解决方法&#xff0c;帮助大家更好地…

python爬虫经典实例(二)

在前一篇博客中&#xff0c;我们介绍了五个实用的爬虫示例&#xff0c;分别用于新闻文章、图片、电影信息、社交媒体和股票数据的采集。本文将继续探索爬虫的奇妙世界&#xff0c;为你带来五个全新的示例&#xff0c;每个示例都有其独特的用途和功能。 1. Wikipedia数据采集 爬…