**问题定义::**存在单一资源,有一组时间区间形式表示的资源使用请求S={S1,S2,S3…Sn}.某一个请求需要使用资源一段时间,并且有开始时间begin 结束时间end。如果两个请求没有时间重复可以,分配到一起,否者不可以。求 在时间内,最多能玩成的请求个数?
例如: 有一间多媒体课室,某一个周末有多个社团想要申请这间课室去举办社团活动,每个社团都有一个对应的申请时间段,比如周六上午8:00-10:00。求出这间课室在这个周末最多能满足几个社团的需求。
解题思路:: 利用贪心算法,选最早结束的活动,保证资源被早时间释放,越早结束剩余的时间越多,安排的社团也就越多。实现整体安排最大化。
伪代码::
初始化 S 是所有需求的集合,A 为空集
对 S 中的需求 Si,根据结束时间早晚排序从早到晚(结束时间)
for Ri int R,do
if Ri与 A 的请求可以共容
A=A并R;
endif
endif
return A
C++代码::
copy的
vector+ 结构体;
#include
#include
#include
using namespace std;
const int maxn=100;
struct S { // 感觉用pair更方便
int begin,end;
} s[maxn];
bool operator<(const S& s1,const S& s2)
{
return s1.end<s2.end;
}
vector<S> ve;
int main()
{
int S_num;
cin>>S_num;
for(int i=0; i<S_num; i++) {
cin>>s[i].begin>>s[i].end;
}
cout<<endl;
sort(s,s+S_num);
ve.push_back(s[0]);
for(int i=1;i<S_num;i++)
{
if(ve[ve.size()-1].end<=s[i].begin)
ve.push_back(s[i]);
}
cout<<ve.size()<<endl;
return 0;
}
仿写
vector+pair
#include
using namespace std;
pair<int,int> p[99];
bool cmp(pair<int,int> p1, pair<int ,int> p2)
{
return p1.second<p2.second;
}
int main()
{
int c;
cin>>c;
for(int i=0; i<c; i++)
cin>>p[i].first>>p[i].second;
cout<<endl;
sort(p,p+c,cmp);
vector<pair<int,int> > ve;
ve.push_back(p[0]);
for(int i=0; i<c; i++)
if(ve[ve.size()-1].second<= p[i].first)
ve.push_back(p[i]);
cout<<ve.size()<<endl;
return 0;
}
问题定义:: 有多个或者无限个相同的资源可以使用 ,有一组以时间形式表示的资源请求R={R1,R2,R3…Rn}; 某个请求想占用资源一段时间,时间开始于begin(i)结束于end(i), 如果连个请求,时间上没有重叠,两请求可以同时存在 ,如何用最少的资源,来满足所有的请求,——也就是做到资源浪费最小化。
例子:: 很多间课室,某个周末有多个社团需要申请课室办活动,每个社团都有一个 对应的申请时间,求最少需要多少间课室才能够满足所有社团的需求.(很多间教室——>多个资源、周末——>时间一定,在固定的一段时间)《 多区间调度问题:Ps: 也就是多个资源分配。
解题思路:: 贪心算法,将需求按照开始时间的早晚进行排序,然后开始为这些资源打标签,每个标签代表都一个资源,需求req-i被打上标签k表示该请求分配到的资源是k。遍历排序后的需求,如果一个需求与某个已分配资源上的其他安排不冲突,则把该需求也放进该资源的安排考虑中;如果冲突,那么应该要给此需求分配新的资源,已用资源数量加一。
伪代码::
对n个需求按照开始时间从早到晚排序
假设排序后需求为R={R1,R2,R3..Rn};
初始化tagsize=1;
for i=1 to n do:
tags={1,2,3...tagsize};
for j=1 to i-1 do
if (Rj与Ri时间区间重叠产生冲突)
tags=tags-{Rj的标签};
endif
endfor
if(tags为空集)
tagsize=tagsize+1
将tagsize贴在Ri上
endif
else
在tags剩下的标签中随便挑一张贴个Ri
endelse
endfor
这个时候每个请求上都有标签,每个标签对应其申请资源编号,
此时tagsize就至少需要的资源量
return tagsize;
C++ 代码::
#include
using namespace std;
struct R {
int b,e,t;
} r[99];
bool operator<(const R&r1,const R&r2)
{
return r1.b<r2.b;// 按时间的开始先后顺序排列
}
int main()
{
int R_mum;
cin>>R_mum;
for(int i=0; i<R_mum; i++) // 录入开始和结束时间
cin>>r[i].b>>r[i].e;
sort(r,r+R_mum); // 排序
int tagsize=1; // 使用的资源数量
r[0].t=0;
bool ts[99];
for(int i=1; i<R_mum; i++) {
memset(ts,true,sizeof(ts));
for(int j=0; j<i; j++) {
if(r[j].e>r[i].b) { //开始时间小于结束时间,活动冲突
ts[r[j].t]=false;//将符合的活动都设为未标记过
}
}
bool just=true;
int tg;// 0-> tagsize 是否存在着没有安的活动
for(int j=0; j<tagsize; j++) {
if(ts[j]) {
just=false; // 标记没安排的活动
tg=j; //有则 取出其下标
break;
}
}
if(just) {// 没有活动能在0-> tasize剩下的活动,只能在占用一个资源
r[i].t=tagsize; // 给某个活动打上在那个资源上开展的标签
++tagsize;// 占用资源加1
} else //如果可以安排这个活动,就把相应的标签贴给这个活动
r[i].t=tg;
}
cout<<tagsize<<endl;
return 0;
}
// 看的稀里糊涂的 ^_^
// 加油!!
问题定义:: 存在单一资源和一组使用资源请求R={R1,R2,R3…Rn};与1,2不同这里的资源从0时刻开始有效(开始接受申请,开始被使用),每一个请求都有个借宿时间end,每个请求都要占用资源一段连续时间占用时间为time。每个请求都希望在end之前完成(单一资源同一时刻只能完成一个请求) 如果我们想完成每个请求,也可以让某些请求有延迟,(也就是在end后才能完成,可以拖延时间,让我们确定一个合理的安排,让所有请求延迟时间中的最大值,是所有可能时间安排最小的。 从时刻0开始,为每个请求req-i分配一个长度time(i)的时间区间,把区间标记为[begin(i), end(i)],其中end(i) = begin(i) + time(i)。如果end(i) > ddl(i),则请求req-i被延迟,延迟时间为delay(i) = end(i) - ddl(i);否则delay(i) = 0。合理安排需求,使得maxDelay = max{delay(1), delay(2), …, delay(n)}是所有可能的安排中最小的。
解题思路:: 心算法 按照时间截止时间ddl 排序,越早截止的任务越早完成,该算法是一个没有空闲 的最优调度 。从时刻0开始处理,知道最后一个请求执行完,释放资源才空闲。
伪代码::
将需求按照截止时间进行排序
* 假设排序后截止时间为 ddl[1]<=...<=ddl[n];
* start=0;
* maxdelay=0;
* for i to n ,do:
* begin [i]=start;
* end[i]=start+time[i];
* start=start+time[i]
* if maxdelay <end[i]-ddl[i]
* l=end[i]-ddl[i];
* endif
* endfor
* return maxdelay;
C++\代码::
#include
using namespace std;
struct R {
int time,ddl;//占用资源时长和 给姐素的时间
int begin,end; //开始和结束的时间
} r[99];
bool operator<(const R& r1,const R& r2)
{
return r1.ddl<r2.ddl;// 按照结束时间排序
}
int main()
{
int R_mum;
cin>>R_mum;
for(int i=0; i<R_mum; i++)
cin>>r[i].time>>r[i].ddl;// 录入
sort(r,r+R_mum); // sort
// cout<
// for(int i=0;i
// cout<
// cout<
int maxdelay=0;// 定义最大的延误时间
int start=0; //从0开始处理请求
for(int i=0; i<R_mum; i++) { //板子
r[i].begin=start; //最开始的时间给begin,自我感觉,没啥用
r[i].end=start+r[i].time;// end 有一点用吧,但是也不用再结构体里定义啊
start=start+r[i].time;// 循环累加时间,每次找到该活动的最早开始时间,也没啥用
if(maxdelay<r[i].end-r[i].ddl)//找出结束时间和当前时间的差最小值,也就是答案
maxdelay=r[i].end-r[i].ddl;
}
// cout<
cout<<maxdelay<<endl; //最先最大延误时间
return 0;
}
感觉好多没用的地方,写个新的吧。
#include
using namespace std;
bool cmp(pair<int,int> p1,pair<int ,int> p2)
{
return p1.first<p2.first;
}
pair<int,int> p[99];
int main()
{
int R_mum;
cin>>R_mum;
for(int i=0; i<R_mum; i++)
cin>>p[i].first>>p[i].second;
sort(p,p+R_mum,cmp);
cout<<endl;
for(int i=0; i<R_mum; i++) //验证是否排序成功
cout<<p[i].first<<" "<<p[i].second<<endl;
int start=0,maxdelay=0;
for(int i=0; i<R_mum; i++) {
int end=start+p[i].first;
start=start+p[i].first;
if(maxdelay<end-p[i].second)
maxdelay=end-p[i].second;
}
cout<<maxdelay<<endl;
return 0;
}