简单的贪心,很容易证明,先尽量多的买b/a小的比较划算。比赛时YY了一下就想出来了,可是WA到比赛结束,估计是精度导致的,换了int输入然后省略了一些浮点数相等的比较之后就AC了。 以后一定要注意。
细节参见代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<map>
#include<list>
#include<cmath>
#include<set>
#include<queue>
#define eps 1e-9
using namespace std;
typedef long long ll;
const double INF = 100000000000;
const int maxn = 100000 + 50;
int T,n,m, A,B;
struct things{
int sum,a,b,id;
double d;
bool operator < (const things& t) const {return d < t.d;}
}t[maxn];
double ans[maxn];
int main() {
freopen("burrito.in","r",stdin);
freopen("burrito.out","w",stdout);
while(~scanf("%d%d%d",&n,&A,&B)){
memset(ans,0,sizeof(ans));
for(int i=0;i<n;i++) {
scanf("%d%d%d",&t[i].sum,&t[i].a,&t[i].b);
t[i].id=i;
if(t[i].b == 0) t[i].d = 0;
else if(t[i].a == 0) t[i].d = INF;
else t[i].d = t[i].b*1.0/t[i].a;
}
sort(t,t+n);
double ansA=0,ansB=0;
for(int i=0;i<n;i++){
if(1.0 * t[i].b * t[i].sum + ansB > B){
double cur = (1.0 * B - ansB) / t[i].b;
ans[t[i].id] = cur;
ansB = B;
ansA += 1.0 * t[i].a * cur;
break;
}
else{
ans[t[i].id] = t[i].sum;
ansB += 1.0 * t[i].b * t[i].sum;
ansA += 1.0 * t[i].a * t[i].sum;
}
}
if(ansA < (double)A) printf("-1 -1\n");
printf("%.9f %.9f\n",ansA,ansB);
for(int i=0;i<n;i++)
printf("%f%c",ans[i],i==n-1?'\n':' ');
}
return 0;
}