POJ 3190 Stall Reservations
思路:利用优先队列,先对区间左端点从小到大排序,优先队列以区间右端点小的为优先级。
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;
struct dd{
int l;
int r;
int ps;
friend bool operator<(struct dd k1,struct dd k2){
return k1.r>k2.r;//以右端点小的为优先级,使得队首的牛是最早使用完机器的牛。
}
}ss[50005];
typedef struct dd dd;
bool cmp(dd a,dd b){
return a.l<b.l;
}
int main(){
int n;
while(scanf("%d",&n)!=EOF){
int s[50005],need=1;//need为需要的机器数,s[i]表示输入时顺序为i的牛所使用的机器编号。
for(int i=0;i<n;i++){
scanf("%d%d",&ss[i].l,&ss[i].r);
ss[i].ps=i;//记录牛的输入时顺序,因为后面sort会打乱顺序。
}
sort(ss,ss+n,cmp);
priority_queue<dd> q;
q.push(ss[0]);
s[ss[0].ps]=1;
for(int i=1;i<n;i++){
if(ss[i].l<=q.top().r)//如果队首的牛还在使用机器,则需再拿一台机器。
s[ss[i].ps]=++need;
else{//如果队首的牛已经使用完机器,则使用他的机器。
s[ss[i].ps]=s[q.top().ps];
q.pop();
}
q.push(ss[i]);
}
printf("%d\n",need);
for(int i=0;i<n;i++)
printf("%d\n",s[i]);
}
return 0;
}
POJ 3040 Allowance
思路:面额大于c的直接给。对于小于c的,先取面额大的,取到不能再取(即再取就会溢出),然后取面额小的取,使得工资尽可能的接近c。
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define INF 10000000
using namespace std;
struct dd{
int v;
int b;
}uu[22];
int tt[22];//tt[i]表示在其中一种组合方式中,第i个面值的所需要的个数(不完全是,见34行)。
bool cmp(struct dd a,struct dd b){
return a.v>b.v;
}
int main()
{
int n,c;
while(scanf("%d%d",&n,&c)!=EOF){
int k=0,sum=0;
for(int i=0;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
if(x>=c) sum+=y;//面值超出c的直接就可以给。
else{
uu[k].v=x;
uu[k++].b=y;
}
}
sort(uu,uu+k,cmp);
while(1){//枚举所有工资的组合方式。
int t=c;
memset(tt,0,sizeof(tt));
for(int i=0;i<k;i++){
tt[i]+=min(t/uu[i].v,uu[i].b);//如果第i个面值的纸币实际数量不够,则直接存储实际数量。
t-=tt[i]*uu[i].v;
if(t<0){
t+=tt[i]*uu[i].v;//不能溢出。
tt[i]=0;//不取
break;
}
else if(t==0) break;
}
if(t>0){
for(int i=k-1;i>=0;i--){
if(uu[i].b){
if(uu[i].b<=tt[i]) continue;// !!!
int s=t%uu[i].v?t/uu[i].v+1:t/uu[i].v;//除法可加快速度。
s=min(s,uu[i].b);
tt[i]+=s;
t-=s*uu[i].v;
if(t<=0) break;
}
}
}
if(t>0) break;
int d=INF;//可发的周数。
for(int i=0;i<k;i++){
if(tt[i])
d=min(d,uu[i].b/tt[i]);
}
sum+=d;
for(int i=0;i<k;i++){
uu[i].b-=d*tt[i];//更新每种纸币的数量。
}
}
printf("%d\n",sum);
}
return 0;
}
/*
3 6
4 3
2 2
1 1
*/