这道题我当时想了好久,也没有想出解的方法,不知道如何贪心,也不认为是dp,后来受高手指导后发现这道题很简单。
这道题的贪心方法和其他题略有不同,一般的贪心是从一开始就开始贪,而这道题是从满足不了题意后开始贪。
当i项任务不能在规定时间完成时,我们就需要把前面的任务“加速”,当然是加速a最大的那一项。
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef struct Item{
ll a, b, d;
bool operator < (const Item &rhs) const{
return a < rhs.a;
}
}Item;
const int MAXN = 1e6 + 100;
int n;
Item it[MAXN];
bool cmp(const Item &lhs, const Item &rhs){
return lhs.d < rhs.d;
}
int main(void)
{
while(~scanf("%d", &n)){
for(int i = 0; i < n; i++) scanf("%lld%lld%lld", &it[i].a, &it[i].b, &it[i].d);
sort(it, it + n, cmp); priority_queue<Item> q;
double cost = 0; ll t = 0;
for(int i = 0; i < n; i++){
q.push(it[i]);
if(t + it[i].b <= it[i].d){
t += it[i].b; continue;
}
ll remain = t + it[i].b - it[i].d;
t = it[i].d;
while(!q.empty() && remain){
Item top = q.top(); q.pop();
cost += (double)(min(top.b, remain)) / top.a;
ll tag = remain;
remain -= min(top.b, tag);
top.b -= min(top.b, tag);
if(top.b) q.push(top);
}
}printf("%.2f\n", cost);
}
return 0;
}