Exams

Vasiliy has an exam period which will continue for n days. He has to pass exams on m subjects. Subjects are numbered from 1 to m.

About every day we know exam for which one of m subjects can be passed on that day. Perhaps, some day you can’t pass any exam. It is not allowed to pass more than one exam on any day.

On each day Vasiliy can either pass the exam of that day (it takes the whole day) or prepare all day for some exam or have a rest.

About each subject Vasiliy know a number ai — the number of days he should prepare to pass the exam number i. Vasiliy can switch subjects while preparing for exams, it is not necessary to prepare continuously during ai days for the exam number i. He can mix the order of preparation for exams in any way.

Your task is to determine the minimum number of days in which Vasiliy can pass all exams, or determine that it is impossible. Each exam should be passed exactly one time.

Input
The first line contains two integers n and m (1 ≤ n, m ≤ 105) — the number of days in the exam period and the number of subjects.

The second line contains n integers d1, d2, …, dn (0 ≤ di ≤ m), where di is the number of subject, the exam of which can be passed on the day number i. If di equals 0, it is not allowed to pass any exams on the day number i.

The third line contains m positive integers a1, a2, …, am (1 ≤ ai ≤ 105), where ai is the number of days that are needed to prepare before passing the exam on the subject i.

Output
Print one integer — the minimum number of days in which Vasiliy can pass all exams. If it is impossible, print -1.

Example
Input
7 2
0 1 0 2 1 0 2
2 1
Output
5

题意:有n天进行考试,有m个科目,每个科目需要d[i]天进行复习.问最少需要多少天才能把所有试考完


从题目可知,我们最少需要num = sum(d)+m天,即所有科目复习的时间加上考试的时间.我们从num天开始判断,num是不是最少的考试天数,直到第n天
每次判断我们从后往前进行判断,因为最后的一次考试能成功,则再不需要判断前面是否需要考这门试了,但是如果是从前面开始循环的话,我们不知道这一天应不应该考试,因为有可能后面的考试必须要在这一天复习,从后面就不需要考虑了.如果考完这一科,就要把其标记,再遇到这门考试,我们就可以用来复习,最后判断复习的时间是否足够.

#include <stdio.h>

int a[100005],d[100005];

int f(int n,int m)
{
    int x,y,z,t;
    int flag[100005]={0};
    int sum  = 0; 
    for(x=n;x>=1;x--)
    {
        if(d[x]!=0&&flag[d[x]]==0)//如果是考试,并且还没考的 
        {
            flag[d[x]]=1;//标记为考完试了 
            sum+=a[d[x]];//要复习的时间增加 
        }
        else if(sum!=0)//如果这课已经考了,并且还没考过试,要复习的时间减一,因为这一天可以用来复习
        sum--;
    }
    if(sum>0)//当sum大于零的时候,代表还要复习,即复习的时间不足 
    {
        return 0;
    }
    for(x=1;x<=m;x++)//还有试没有考 
    {
        if(!flag[x])
        {
            return 0;
        }
    }   
    return 1;
}


int main()
{
    int x,y,z,t,n,m;
    int t = 0;
    scanf("%d%d",&n,&m);
    for(x=1;x<=n;x++)
    {
        scanf("%d",&d[x]);
    }
    for(x=1;x<=m;x++)
    {
        scanf("%d",&a[x]);
        mid += a[x];
    }
    t += m;//t为最少的考试天数
    for(x=t;x<=n;x++)
    {
        if(f(x,m))
        break;
    }
    if(x<=n)
    printf("%d\n",x);
    else
    printf("-1\n");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值