Codeforces Round #377 (Div. 2)-D. Exams

传送门

因为天数越大通过所有考试的可能性就越大,具有单调性所以可以二分天数,然后check的话,就要用到贪心的思想从后往前扫(因为越晚考试复习的时间就越多),设变量统计1到mid通过的考试的数量,还有通过这些考试所需要的复习时间。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int vis[maxn],a[maxn],d[maxn],n,m;
bool check(int mid)
{
    int need=0,cnt=0;//need表示通过cnt个考试还需要的总的复习时间
    for(int i=1;i<=m;i++) vis[i]=0;
    for(int i=mid;i>=1;i--)
    {
        if(d[i]&&!vis[d[i]])
        {
            need+=a[d[i]];
            vis[d[i]]=1;
            cnt++;
        }
        else
            if(need>0) 
                need--;
    }
    if(cnt!=m||need!=0)
        return false;
    else
        return true;


}
int main()
{
    int ans=-1,low,high,mid;
    scanf("%d %d",&n,&m);
    low=m;
    for(int i=1;i<=n;i++)
        scanf("%d",&(d[i]));
    for(int i=1;i<=m;i++)
        scanf("%d",&(a[i])),low+=a[i];
    high=n;
    while(low<=high)
    {
        mid=(low+high)/2;
        if(check(mid))
        {
            ans=mid;
            high=mid-1;
        }
        else
            low=mid+1;
    }
    printf("%d
",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/eason9906/p/11754858.html