Codeforces Round #610 (Div. 2) C. Petya and Exam(贪心)

题目链接:https://codeforces.com/contest/1282/problem/C

 

题目大意:

  有n道题,一共T的答题时间,简单题需要时间a,难题需要b,每道题都有ddl,如果实际答题时间到达ti,那么这道题就必须要做,否则只能拿零分,每题一分,问最多能拿几分

 

题目思路:

  日常被C题卡。。。哭了。我刚开始想简单了,就直接双指针,如果做了一个题,其他题ddl到了,就一排全部带走,否则尽量做简单题。反例太多了。。。。。后来又看了题解。。。菜!强行总结出这种题技巧,就是只要出现过了某个时间点就会变性质的题目,那么这个时间点的附近时间点可能就是题目的关键!
  不卖关子了,首先我们可以发现,对于每个ddl的前一秒,如果能在这个时间点完成必做任务,而且没有超时,那么这个时间点就不会产生关联到其他题目的关键时间点。这个时间点的好处在于,把动态的过程(如果时间超过了某一题ddl,这题变成必做会影响结束时间)变成了静态(不再有题目变成必做,所以就是不用怕会有新的必做题出现)。这道题的做法就是,搞出所有题目ddl-1再加上T也就是考试结束时间,这些作为关键点,排序去重。然后判断每个时间点能够得到的分数。怎么判断呢?首先先看这个时间段有多少必做简单题数量c1c1和必做难题数量c2c2,直接用while即可,只要ddl小于等于正在枚举的时间点tt,那就是必做题,那么剩余时间就是tac1bc2t-a*c1-b*c2,如果剩余时间是负数,就说明这个时间点不够完成必做任务直接歇逼,如果还有剩,那么聪明的大家伙肯定想到了,可以用来不是必做的题,由于简单题需要的时间少,所以先做简单题,min(rst/a,pp1c1)min(rst/a,pp1-c1) 表示还能做多少简单题,要么是时间不够了,要么是题不够了,难题也一样,然后就能得到这个时间点一共能做的题,取max这题就结束战斗了。

 

以下是代码:

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
const int MAXN = 2e5+5;
const int MOD = 10007;
int x[MAXN],y[MAXN],p[MAXN];
int h[MAXN],k[MAXN];
int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n,T,a,b;
        scanf("%d%d%d%d",&n,&T,&a,&b);
        rep(i,1,n){
            scanf("%d",&x[i]);
        }
        int pos=0;
        int pp1=0,pp2=0;
        rep(i,1,n){
            scanf("%d",&y[i]);
            if(x[i])k[++pp2]=y[i];
            else h[++pp1]=y[i];
            p[++pos]=y[i]-1;
        }
        p[++pos]=T;
        sort(p+1,p+pos+1);
        sort(k+1,k+pp2+1);
        sort(h+1,h+pp1+1);
        pos=unique(p+1,p+pos+1)-p-1;
        ll ans=0;
        int c1=0,c2=0;
        h[pp1+1]=1e9+7;
        k[pp2+1]=1e9+7;
        rep(i,1,pos){
            while(h[c1+1]<=p[i])c1++;
            while(k[c2+1]<=p[i])c2++;
            ll temp=c1+c2;
            ll rst=p[i]-(ll)c1*a-(ll)c2*b;
            if(rst<0)continue;
            int num=min(rst/a,(ll)pp1-c1);
            temp+=num;
            rst-=num*a;
            num=min(rst/b,(ll)pp2-c2);
            temp+=num;
            ans=max(ans,temp);
        }
        printf("%I64d\n",ans);
    }
}

发布了262 篇原创文章 · 获赞 24 · 访问量 2万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览