Codeforces Round #610 (Div. 2)C(贪心,思维)

沿时间轴枚举,发现关键时间点在于新题目被锁定的前一时间,那是新的题目还没有被锁定并且距离旧的题目已经被锁定的最晚时间,对这些时间点进行操作

 1 #define HAVE_STRUCT_TIMESPEC
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 typedef struct node{
 5     int flag,s;
 6 };
 7 node c[200007];
 8 bool cmp(node x,node y){
 9     if(x.s!=y.s)
10         return x.s<y.s;
11     return x.flag<y.flag;
12 }
13 int main(){
14     ios::sync_with_stdio(false);
15     cin.tie(NULL);
16     cout.tie(NULL);
17     int m;
18     cin>>m;
19     while(m--){
20         int n,t,a,b;
21         cin>>n>>t>>a>>b;
22         int suma=0,sumb=0;
23         for(int i=1;i<=n;++i){
24             cin>>c[i].flag;
25             if(c[i].flag)
26                 ++sumb;
27         }
28         suma=n-sumb;
29         for(int i=1;i<=n;++i)
30             cin>>c[i].s;
31         sort(c+1,c+1+n,cmp);
32         int now=0;
33         int tempa=0,tempb=0;
34         int ans=0;
35         for(int i=1;i<=n;++i){//枚举当前时间c[i].s-1,即为当前题目被锁定的时间以前
36             //当前时间及以前被锁定的题目都要完成,当前时间只完成前i-1道已锁定的题目以及空余时间可以做的题目
37             int numa=min(suma-tempa,(c[i].s-1-now)/a);//如果完成锁定题目以外还有空余时间,计算得到空余时间可以解决的最大简单题数量
38             int numb=min(sumb-tempb,(c[i].s-1-now-numa*a)/b);//如果解决完简单题还有空余时间,计算得到空余时间可以解决的最大复杂题数量
39             if(numa<0)
40                 numa=0;
41             if(numb<0)
42                 numb=0;
43             if(now<=c[i].s-1)//now表示完成已经锁定的题目(前i-1道)需要的时间,如果当前时间可以完成这些已经锁定的题目,答案才会更新
44                 ans=max(ans,numa+numb+i-1);
45             if(c[i].flag){
46                 now+=b;
47                 ++tempb;//已锁定的复杂题
48             }
49             else{
50                 now+=a;
51                 ++tempa;//已锁定的简单题
52             }
53             if(now>t)//完成锁定的题目需要的时间超出上限,那么就做不了更多的题目了,break
54                 break;
55             if(i==n)//如果全部题目都已经锁定并且完成时间不超出上限
56                 ans=n;
57         }
58         cout<<ans<<"
";
59     }
60     return 0;
61 }
保持热爱 不懈努力 不试试看怎么知道会失败呢(划掉) 世上无难事 只要肯放弃(划掉)
原文地址:https://www.cnblogs.com/ldudxy/p/12197664.html