[atAGC053D]Everyone is a winner

下面将直接叙述本题的做法——

维护序列$\{T_{i}\}$,初始$T_{i}$为(强制所有人均按时间倒序做题时)第一个解决前$i$道题的时间

从后往前考虑每一个人,对第$i$个人按如下方式确定其解决题目的顺序:

1.显然前$i$道题和后$n-i$道题内均倒序做题,因此仅需要确定前$i$道题(的分布)即可

2.设前$i$道题中分别选择$x,y$和$z$道时间为1,2和3的题目,在$t=x+2y+3z\le T_{i}$的基础上,依次最大化$t$和$x$

记$S_{i,j}$为第$i$个人解决前$j$道题的时间,那么将$\forall 1\le j<i,T_{j}=\min (T_{j},S_{i,j})$

另外,无解的情况即在第2步中无法选出$i$道题使得$t\le T_{i}$

关于上述做法的正确性,并不太会证

关于实现,注意到$T_{i}$和$S_{j,i}$均可表示为斜率$\in \{1,2,3\}$的凸包(包括初始的$T_{i}$),进而即可维护

时间复杂度为$o(n)$,可以通过

(代码中为了方便,最大化$t$时暴力减小$t$并判定,注意到每次$t$递减,因此均摊是$o(n)$的)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 200005
 4 #define oo 0x3f3f3f3f
 5 struct Line{
 6     int a,b,c;
 7     Line(int aa=oo,int bb=oo,int cc=oo){
 8         a=aa,b=bb,c=cc;
 9     }
10     int get_val(int x){
11         return min(min(a+x,b+2*x),c+3*x);
12     }
13 }T;
14 int t,n,a[N],b[N],c[N];
15 Line merge(Line x,Line y){
16     return Line(min(x.a,y.a),min(x.b,y.b),min(x.c,y.c));
17 }
18 int main(){
19     scanf("%d",&t);
20     while (t--){
21         scanf("%d",&n);
22         T=Line();
23         for(int i=1;i<=n;i++){
24             scanf("%d%d%d",&a[i],&b[i],&c[i]);
25             T=merge(T,Line(b[i]+2*c[i],c[i],0));
26         }
27         bool flag=0;
28         for(int i=n;i;i--){
29             //y+z=i-x,2y+3z=t-x,
30             //y=3i-t-2x,z=t+x-2i
31             //0<=x<=a[i],0<=y<=b[i],0<=z<=c[i]
32             //(3i-t-b[i]+1)/2<=x<=(3i-t)/2
33             //2i-t<=x<=c[i]+2i-t
34             int t=T.get_val(i),x;
35             while (t>=0){
36                 x=min(min(a[i],(3*i-t)/2),c[i]+2*i-t);
37                 if (x>=max(max(0,(3*i-t-b[i]+1)/2),2*i-t))break; 
38                 t--;
39             }
40             if (t<0){
41                 flag=1;
42                 break;
43             }
44             int y=3*i-t-2*x,z=t+x-2*i;
45             T=merge(T,Line(y+2*z,z,0));
46         }
47         if (flag)printf("No\n");
48         else printf("Yes\n");
49     }
50     return 0;
51 }
View Code

 

posted @ 2022-01-13 13:57  PYWBKTDA  阅读(107)  评论(0编辑  收藏  举报