签到题,是这场比赛第二简单的题。
解法
考虑要在第 $a_i$ 天交付 $b_i$ 件货物,我们就将订单按照 $a_i$ 排序。在每件订单之前(包括这个订单)工厂最多可以生产 $a_i \times k$ 件货物,如果 $\sum \limits _{i=1} ^{i \le a_i} b_i > a_i \times k$,则一定不能按时交付。否则如果一直满足 $\sum \limits _{i=1} ^{i \le a_i} b_i \le a_i \times k$,则有解。
实现方案一
排完序后对 $b_i$ 求一遍前缀和,记作 $pre_i$,每求完一次前缀和就判断一下是否满足 $pre_i \le a_i \times k$,如果不满足则无解,如果一直满足则有解。
实现方案二
排完序后遍历从 $1$ 到 $n$ 的订单,对于每次订单,我们可以记录一下交付完这次订单最多有多少剩余货物,定义为 $last_i$,$last_i = (a_i - a_{i-1}) \times k + last_i - b_i$($i \ge 2$),我们认为 $last_1 = a_1 \times k - b_1$。如果 $\exists i \in [1,n]$ 使得 $last_i < 0$,则无解,否则有解。
代码(实现方案二)
#include<bits/stdc++.h>
using namespace std;
namespace fast_IO
{
/*
快读快写代码,可忽略。
*/
};
using namespace fast_IO;
#define int long long
int t,n,k,last,flag;
struct node
{
int a,b;
};
node arr[200];
inline bool cmp(const node &x,const node &y)
{
return x.a<y.a;
}
signed main()
{
read(t);
while(t--)
{
read(n),read(k),last=0,flag=0;
for(int i=1;i<=n;i++) read(arr[i].a),read(arr[i].b);
sort(arr+1,arr+1+n,cmp);
if(arr[1].a*k<arr[1].b)
{
write("No\n");
continue;
}
last=arr[1].a*k-arr[1].b;
for(int i=2;i<=n;i++)
{
if((arr[i].a-arr[i-1].a)*k+last<arr[i].b)
{
write("No\n"),flag=1;
break;
}
last=(arr[i].a-arr[i-1].a)*k+last-arr[i].b;
}
if(!flag) write("Yes\n");
}
fwrite(Ouf,1,p3-Ouf,stdout),fflush(stdout);
return 0;
}