博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【算法概论】贪心算法:区间调动问题
阅读量:4176 次
发布时间:2019-05-26

本文共 3551 字,大约阅读时间需要 11 分钟。

区间调动问题 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) 在可选工作中,每次选取与最小可选工作有重叠的部分。

       证明看这里?

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

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

       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 
#include
#include
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
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的排序很方便!见:。

       贪心法 - 递归版:

#include 
#include
#include
using namespace std;//存储区间信息struct Val{ int start = 0; int finish = 0;};int num;vector
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 
#include
#include
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
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
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://wxtai.baihongyu.com/

你可能感兴趣的文章
Linux下rz,sz与ssh,SecureCRT的配合使用
查看>>
一个使用Pro*C实现增删改查的小例子
查看>>
Save could not be completed. Eclipse国际化的问题解决
查看>>
Xblo(JSP+Servlet+JavaBean+Oracle单用户Blog)
查看>>
Unable to use IEC module under PortablePython_1.1_py2.5.4
查看>>
实用英文地址书写格式
查看>>
在oracle中通过connect by prior来实现递归查询!
查看>>
百度空间如何才能另存为 mht
查看>>
How to Reset or Change Microsoft Office 2007 Product License Key or Volume License Key (VLK)
查看>>
使用java concurrent调用xmlp api生成pdf
查看>>
Oracle日期计算之INTERVAL
查看>>
Oracle PL/SQL之EXCEPTION
查看>>
Oracle PL/SQL之EXCEPTION -- WHEN OTHERS THEN
查看>>
Oracle PL/SQL之VARCHAR2 QUALIFIER
查看>>
Oracle PL/SQL之处理index不连续的table类型变量
查看>>
Oracle PL/SQL之嵌套表(Nested Table)
查看>>
Oracle PL/SQL之令人不解的提示(nls_date_format)
查看>>
Oracle PL/SQL之GROUP BY ROLLUP
查看>>
Oracle PL/SQL之GROUP BY CUBE
查看>>
蓝桥杯2018省赛 - A3 乘积尾零
查看>>