Assigning Workstations
题目意思 : 有n人,数量足够多的机器,机器没人用m分钟后自己上锁,让你帮管理员分配,使得解锁的次数最少,输出最多多少人不用解锁机器。
解题思路 :运用贪心,重要的一点是运用优先队列,否则容易超时;
贪心策略 :用优先队列存储人使用机子的结束时间。
详见代码注释。
超时代码(一样的思路没带priority_queue):
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
struct node{
long long shi;
long long mo;
node(long long shi,int mo):shi(shi),mo(mo){}
node(){}
};
node pp[300010];
long long jizi[300010];
bool cmp(node a,node b)
{
if(a.shi==b.shi)return a.mo < b.mo;
return a.shi < b.shi;
}
int main()
{
int n;
int t;
long long a,b;
while(scanf("%d%d",&n,&t)!=EOF)
{
for(int i=1;i<=n;i++)
{
scanf("%lld%lld",&a,&b);
pp[i].shi = a;
pp[i].mo = a+b;
}
sort(pp+1,pp+n+1,cmp);
memset(jizi,0,sizeof(jizi));
int jizishu = 0;
int sum = 0;
for(int i=1;i<=n;i++)
{
a = pp[i].shi;
b = pp[i].mo;
for(int j=1;j<=jizishu+1;j++)
{
if(jizi[j]==0){sum++;jizishu++;jizi[j]=b;break;}
if(a>=jizi[j]&&a<=jizi[j]+t)
{jizi[j] = b;break;}
}
}
printf("%d\n",n-sum);
}
return 0;
}
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
struct node{
int shi;
int mo;
bool operator < (const node& b)
{
if(shi==b.shi)return mo < b.mo;
return shi < b.shi;
}
};
node pp[300010];
priority_queue<int,vector<int>,greater<int> >op;
int main()
{
int n;
int a,b;
int t;
while(scanf("%d%d",&n,&t)!=EOF)
{
for(int i=0;i<n;i++)
{
scanf("%d%d",&a,&b);
pp[i].shi = a;
pp[i].mo = a+b;
}
sort(pp,pp+n);
while(!op.empty())op.pop();//记得清空
int sum = 0;
for(int i=0;i<n;i++)
{
a = pp[i].shi;
b = pp[i].mo;
if(op.empty())//空队列代表没有机子可用,要重新开一台;
{
sum++;
op.push(b);
}
else
{
while(!op.empty())
{
int p = op.top();
if(a>=p&&a<=p+t)
{
op.pop();
op.push(b);
break;
}
else if(a<p)//上机时间冲突,就得重新开一台
{
sum++;
op.push(b);
break;
}
op.pop();
}
if(op.empty())//如果机子都已经锁了,就得开一台机子
{
sum++;
op.push(b);
}
}
}
printf("%d\n",n-sum);
}
return 0;
}
语文老师估计会打死我。自己想象上机过程,很容易想到贪心,主要是处理怎么不超时。
水波。