有n个休息时刻,你需要把这n个休息时刻安排到尽量少的天中,使得每两个休息时刻的间隔大于d分钟,一天有m分钟。
注意两天之间的间隔大于d分钟。
我们贪心选取时刻,每次把尽量小的时刻安排进这一天中,如果没有能安排进这一天的时刻了,我们就必须新开一天,并且选取最小的时刻安排进第二天中,然后继续贪心。
这样我们必须有一种数据结构来快速查找和删除。
那当然是set啦!
方法就是,开一个set把所有时刻存储起来,然后每次找到最小的能安排进这一天的时刻,把这个时刻安排进这一天。如果找不到就安排一个最小的时刻到第二天。每次安排完一个时刻就把这个时刻从set中删除。找最小的时刻用lower_bound就可以了。
注意:假设我们有一个set,名字为a,我们要查找元素x,使用lower_bound(a.begin(),a.end(),x)的时间复杂度为,而使用a.lower_bound(x)的时间复杂度为
。
时间复杂度:
代码:
#include
using namespace std;
#define MAXN 200010
struct data
{
int val,id;
bool operator<(const data d)const
{
return val a;
int main()
{
scanf("%d%d%d",&n,&m,&d);
for(int i=1;i<=n;++i)
{
scanf("%d",&x.val);x.id=i;
a.insert(x);
}
int now=(*a.begin()).val,cnt=1;
pos[(*a.begin()).id]=1;
a.erase(a.begin());
for(int i=2;i<=n;++i)
{
data x;x.val=now+d+1;
auto p=a.lower_bound(x);
if(p!=a.end())
{
pos[(*p).id]=cnt;
now=(*p).val;
a.erase(p);
continue;
}
++cnt;
p=a.begin();
pos[(*p).id]=cnt;
now=(*p).val;
a.erase(p);
}
printf("%d\n",cnt);
for(int i=1;i<=n;++i)printf("%d ",pos[i]);
}