【算法概论】贪心算法:区间调动问题

2024-03-10 01:38

本文主要是介绍【算法概论】贪心算法:区间调动问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

区间调动问题 Interval Scheling

题目描述:

       Job j starts at sj and finishes at fj .
       Two jobs compatible if the intervals [si,fi) and [sj,fj) do not overlap.
       Goal:find maximum subset of mutually compatible jobs.

❗算法描述❗: 

       对于这个问题,使用贪心算法描述的话,有以下几种考虑:

       a) 每次选取开始时间最早的;

       b) 每次选取结束时间最早的;

       c) 每次选取用时最短的;

       d) 在可选工作中,每次选取与最小可选工作有重叠的部分。

       证明看这里?https://blog.csdn.net/luoweifu/article/details/18195607

       b)是正确的思路,因为:

       结束时间最早, 所以取相同数量的工作肯定它最早结束或至少不晚;如果后面还有工作,那么加入到结束最早算法的空间更大,因此就不会存在比它更多工作的可能。(这段话转自https://www.cnblogs.com/yjlblog/p/7506887.html,这个博主的空间真的超好看了?)

       so,代码的思路?

       ① Sort fi

       ② Select the first job

       ③ Pick the first job i such that si ≥ fj, where job j is the most recently selected job.

代码:

       贪心法 - 非递归版:

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;//存储区间信息
struct Val
{int start = 0;int finish = 0;
};bool comp(const Val &a, const Val &b);int main()
{int num;cout << "请输入区间个数:" << endl;cin >> num;vector<Val> vals(num);cout << "请输入各区间的起点坐标和终点坐标:" << endl;for (int i = 0; i < num; ++i){cin >> vals[i].start>> vals[i].finish;}//依据 val[i].finish 进行排序sort(vals.begin(), vals.end(), comp);/*检验排序的结果√for (int i = 0; i < num; ++i){cout << vals[i].start << vals[i].finish;}*/int temp = 0;						//存储已被选入的上一区间的终点for (int i = 0; i < num; ++i){//如果区间 vals[i] 与 被选入的上一区间 没有重叠if (vals[i].start >= temp){cout << vals[i].start << ' ' << vals[i].finish << endl;			//将区间 vals[i] 选入temp = vals[i].finish;			//更新 temp 的值}}return 0;
}bool comp(const Val &a, const Val &b)
{return a.finish < b.finish;
}

       这里用到了:

       ① 结构体:把区间的信息定义成结构体,然后再用vector数组,真的很方便!

       ② 承接上面vector,这里代码首先是要根据区间终点进行排序的,vector的排序很方便!见:关于C++中vector和set使用sort方法进行排序。

       贪心法 - 递归版:

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;//存储区间信息
struct Val
{int start = 0;int finish = 0;
};int num;
vector<Val> vals;bool comp(const Val &a, const Val &b);
void IS_Recursive(int i, int temp);int main()
{cout << "请输入区间个数:" << endl;cin >> num;cout << "请输入各区间的起点坐标和终点坐标:" << endl;for (int i = 0; i < num; ++i){int temp1, temp2;cin >> temp1 >> temp2;Val temp;temp.start = temp1;temp.finish = temp2;vals.push_back(temp);}//依据 val[i].finish 进行排序sort(vals.begin(), vals.end(), comp);int temp = 0; 			//存储已被选入的上一区间的终点IS_Recursive(0, temp);return 0;
}void IS_Recursive(int i, int temp)
{if (i == num){return;}else{//如果区间 vals[i] 与 被选入的上一区间 没有重叠if (vals[i].start >= temp){cout << vals[i].start << ' ' << vals[i].finish << endl;			//将区间 vals[i] 选入temp = vals[i].finish;			//更新 temp 的值}IS_Recursive(i + 1, temp);}
}bool comp(const Val &a, const Val &b)
{return a.finish < b.finish;
}

       动态规划的版本:

#include <iostream>
#include <vector>
#include <algorithm>using namespace std;//存储区间信息
struct Val
{int start = 0;int finish = 0;
};bool comp(const Val &a, const Val &b);int main()
{int num;cout << "请输入区间个数:" << endl;cin >> num;vector<Val> vals(num);cout << "请输入各区间的起点坐标和终点坐标:" << endl;for (int i = 0; i < num; ++i){cin >> vals[i].start >> vals[i].finish;}//依据 val[i].finish 进行排序sort(vals.begin(), vals.end(), comp);//动态规划vector<int> dp(num);dp[0] = 1;for (int i = 1; i < num; ++i){int flag = 0;							// flag 用于标记一段区间之前是否有其无重叠的区间,有标记为1,无标记为0//查找区间在 vals[i] 前一个无重叠的区间for (int j = i - 1; j >= 0; --j){if (vals[j].finish <= vals[i].start){dp[i] = max(dp[j] + 1, dp[i - 1]);		// dp[j] + 1 表示 选择vals[i]区间,dp[i - 1] 表示 不选择vals[i]区间flag = 1;break;}}if (flag == 0){dp[i] = 1;				//如果第 i 区间之前没有不重叠的区间,则dp[i] = 1}}cout << dp[num - 1] << endl;return 0;
}bool comp(const Val &a, const Val &b)
{return a.finish < b.finish;
}

       动态规划的思想参考了:【动态规划-贪心】区间调度问题

这篇关于【算法概论】贪心算法:区间调动问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/792587

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

usaco 1.3 Barn Repair(贪心)

思路:用上M块木板时有 M-1 个间隙。目标是让总间隙最大。将相邻两个有牛的牛棚之间间隔的牛棚数排序,选取最大的M-1个作为间隙,其余地方用木板盖住。 做法: 1.若,板(M) 的数目大于或等于 牛棚中有牛的数目(C),则 目测 给每个牛牛发一个板就为最小的需求~ 2.否则,先对 牛牛们的门牌号排序,然后 用一个数组 blank[ ] 记录两门牌号之间的距离,然后 用数组 an

购买磨轮平衡机时应该注意什么问题和技巧

在购买磨轮平衡机时,您应该注意以下几个关键点: 平衡精度 平衡精度是衡量平衡机性能的核心指标,直接影响到不平衡量的检测与校准的准确性,从而决定磨轮的振动和噪声水平。高精度的平衡机能显著减少振动和噪声,提高磨削加工的精度。 转速范围 宽广的转速范围意味着平衡机能够处理更多种类的磨轮,适应不同的工作条件和规格要求。 振动监测能力 振动监测能力是评估平衡机性能的重要因素。通过传感器实时监

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO