1、本题用贪心法以及优先队列,首先按照截止日期排序,然后用一个变量T记录时间,若T大于截止日期,则利用优先队列,选择当前最大的a值来将T减小。如果将b用完了,则将这个a出队。这样一直减,直到T等于截止日期。
2、要注意的是每次队列都要清空。
3、比较坑爹的是输出的时候用%lf是错的,改成%f就对了。。。原因似乎是历史遗留问题,当且仅当在POJ且用g++时,会出错,用c++是不会出错的。所以以后记住:double变量读入时利用%lf,输出时利用%f,或者直接就cout了。
#include<cstdio>#include<utility>
#include<queue>
#include<algorithm>
#include<cmath>
using namespace std;
const double EPS=1e-7;
int dcmp(double a,double b){
if(abs(a-b)<EPS) return 0;
if(a>b) return 1;
else return -1;
}
struct Dat{
int a,b,d;
double c;
bool operator <(const Dat&rhs) const{
return a<rhs.a;
}
Dat(){c=0;}
Dat(int x,int y,int z){
a=x;b=y;d=z;c=0;
}
};
bool cmp(const Dat&a,const Dat&b){
return a.d<b.d;
}
priority_queue<Dat> que;
int n;
Dat t[150000];
int main(){
while(scanf("%d",&n)==1){
while(!que.empty()) que.pop();
for(int i=0;i<n;i++){
scanf("%d%d%d",&t[i].a,&t[i].b,&t[i].d);
t[i].c=0;
}
sort(t,t+n,cmp);
double sum=0;
double T=0;
for(int i=0;i<n;i++){
que.push(t[i]);
T+=(double)t[i].b;
while(dcmp(T,(double)t[i].d)>0){
Dat pt=que.top();
que.pop();
double x=(T-(double)t[i].d)/(double)pt.a;
if(dcmp((double)pt.b/(double)pt.a,pt.c+x)>0){
pt.c+=x;
sum+=x;
T-=x*(double)pt.a;
que.push(pt);
break;
}else{
x=(double)pt.b/(double)pt.a-pt.c;
pt.c+=x;
sum+=x;
T-=x*(double)pt.a;
}
}
}
printf("%.2f\n",sum);
}
return 0;
}