D. Exams (Thinking + Dichotomy + Greedy)

https://codeforces.com/contest/732/problem/D


Ideas:

At first I thought it was a dp problem and found that the complexity was not enough. In this case, the answer should be monotonic and dichotomous. Consider checking.

Suppose the enumeration is completed in x days.

We will update (all the time to complete the exam) within x days to the last time (deadline)

Review when you have free days. You can only go to the exam when you meet the deadline of the exam. If there is not enough time, adjust the dichotomous time. If you have enough time for this exam, you can use it to review other subjects.

Finally, judge whether all the exams in this round have been taken. (wa22)

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=1e5+1000;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL d[maxn],a[maxn];
bool check(LL x,LL m){
    map<LL,LL>map1;
    for(LL i=1;i<=x;i++){
        if(d[i]!=0){
            map1[d[i]]=i;///更新为该考试的deadline
        }
    }
    LL freeday=0;
    for(LL i=1;i<=x;i++){
        if(d[i]==0) freeday++;
        else{
            if(i==map1[d[i]]){
               freeday-=a[d[i]];
               if(freeday<0) return false;
               map1[d[i]]=-1;///考完了以后就拿来复习其他的
            }
            else freeday++;
        }
    }
    for(LL i=1;i<=m;i++){
        if(map1[i]!=-1){
            return false;
        }
    }
    if(freeday>=0) return true;
    else return false;
}
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n,m;cin>>n>>m;
  for(LL i=1;i<=n;i++) cin>>d[i];
  for(LL i=1;i<=m;i++) cin>>a[i];
  LL l=1;LL r=n+1;
  while(l<r){
    LL mid=(l+r)>>1;
    if(check(mid,m) ) r=mid;
    else l=mid+1;
    ///debug(mid)
  }
  if(l==n+1){
    cout<<"-1"<<"\n";
  }
  else{
    cout<<l<<"\n";
  }
return 0;
}

 

Guess you like

Origin blog.csdn.net/zstuyyyyccccbbbb/article/details/114969507