解法
对于每天的a
和b
,我们不妨假设所有的时间都用来coding,这样能得到totalC
的coding时间
- 显然,如果
totalC<a
,这天显然不能完成 - 否则,我们假设
able = totalC-a
,这表示多出来了able
的coding时间,这些时间可以转化成吃饭时间
我们肯定更prefer效率高的转化,比如我同样减少1单位的coding时间,在不同的timeslot可能会增加不同的吃饭时间
所以我们要把slots按照 E C \frac{E}{C} CE从大到小排序,然后依次开始减,如果在able
减到0之前能达到b
,那么这天是可行的
这是 O ( D S ) O(DS) O(DS)复杂度的
现在要继续优化:
- 如果有很多天,a相同,但是b不同,我们只需要求出来对于同一个a,当
able
为0时可以获得的最大吃饭时间是maxE
。在这些天里,如果b不超过maxE
,那么可以做到,否则不行 - 当我们做完
a1
的转化后,得到一个maxE1
,然后我们要做a2
的转化,并且a2<a1
。显然,在a1
转化里被转化成吃饭的时间在a2
转化里也需要被转化成吃饭的时间。所以我们可以对a从大到小排序,这样每次不用再从头遍历slots。
要注意的是,优化完之后,当从某个slot退出的时候,它可能并未完全转化,要处理一下这个问题
#include <stdio.h>
#include <string>
#include <iostream>
#include <memory.h>
#include <stdlib.h>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <functional>
#define MAXD 100010
#define MAXS 100010
#define ZERO 10e-6
#define NINF -100000
#define INF 65536
using namespace std;
typedef long long lld;
class SLOT{
public:
int c,e;
bool operator < (const SLOT &b) const {
return b.c*e>c*b.e;
}
};
int D,S;
map<int, vector<pair<int,int>>> days;
SLOT slots[MAXS];
bool isEQ(double a, double b) {
return fabs(a-b)<=ZERO;
}
bool isLE(double a, double b) {
return isEQ(a,b) || a<b;
}
double max(double x, double y) {
return isLE(x,y)?y:x;
}
double min(double x, double y) {
return isLE(y,x)?y:x;
}
string solve() {
string ans(D,'Y');
int totalC = 0;
for(int i=0;i<S;++i) totalC += slots[i].c;
double nowB = 0;
int used = 0;
int j = 0;
for (auto ele = days.end(); ele!=days.begin();) {
ele--;
int a = ele->first;
if (totalC<a) {
for(auto &bb:ele->second) {
ans[bb.second] = 'N';
}
} else {
int able = totalC - a;
for(;j<S;++j) {
int change = min(slots[j].c-used, able);
nowB += 1.0*change/slots[j].c*slots[j].e;
able -= change;
if (able==0) {
used += change;
break;
} else used = 0;
}
for(auto &bb:ele->second) {
if (bb.first>(int)nowB) ans[bb.second] = 'N';
}
totalC = able+a;
}
}
return ans;
}
int main() {
int t;
scanf("%d",&t);
for(auto round=1;round<=t;++round) {
scanf("%d%d",&D,&S);
for(int i=0;i<S;++i) {
scanf("%d%d",&slots[i].c,&slots[i].e);
}
sort(slots,slots+S);
days.clear();
for(int i=0;i<D;++i) {
int a,b;
scanf("%d%d",&a,&b);
if (days.find(a)==days.end()) {
days[a] = vector<pair<int,int>>();
}
days[a].push_back(make_pair(b,i));
}
printf("Case #%d: %s\n",round, solve().c_str());
}
}