CodeForces 732D Exams

17 篇文章 0 订阅
16 篇文章 0 订阅

题目:

https://vjudge.net/problem/CodeForces-732D

题解:
有趣的二分套贪心。
二分是学姐推荐题的时候说的,,如果自己瞎做不一定能想出来。。。。

二分通过考试的时间
check函数
考虑如果有一门课在i天可以考,在i+j天也可以考,那么就在i+j天考
证明:对于i+j以后的天数,由于这门课的复习和考试时间不变,无影响;
对于i+j天以前的天数,显然为其余的科目留下了更多的准备方案,更优;

依据这个思想,将数组倒序for一遍;
若某天的考试科目没有考过,压入栈中;
若某天的考试科目考过或不能考试,就用来准备栈顶科目(栈顶科目的考试时间早,需要优先准备)。

真的是随便贪心交了一下,,居然就过了???

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100000+5000,M=100000+5000;
int S[M],ned[M],a[N],b[M];
bool is[M];
int cnt,tot,n,m,l,r;
void init(){
    is[0]=1;
    for(int i=1;i<=m;i++) {
        ned[i]=-b[i];
        is[i]=0;
    }
    tot=0;
    cnt=0;
}
bool check(int x){
    init();
    for(int i=x;i>=1;i--){
        if(!is[a[i]]) {
            is[a[i]]=1;
            S[++tot]=a[i];
            continue;
        }
        ned[S[tot]]++;
        if(ned[S[tot]]==0) tot--,cnt++;
        if(tot==0&&cnt==m) return true;
    }
    return false;
}
int main(){
    scanf("%d%d",&n,&m);
    l=m;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=m;i++) scanf("%d",&b[i]),l+=b[i];
    r=n+5;l-=1;
    //printf("%d %d\n",l,r);
//  int tmp;
//  cin>>tmp;
//  check(tmp);
    while(r-l>1){
        int mid=r+l>>1;
        if(check(mid)) r=mid;
        else l=mid;
    }
    if(r>n) printf("-1");
    else printf("%d",r);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值