codeforces #377D exams

来源:互联网 发布:企业网络课程平台 编辑:程序博客网 时间:2024/05/16 06:19
D. Exams
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

Examples
input
7 20 1 0 2 1 0 22 1
output
5
input
10 30 0 1 2 3 0 2 0 1 21 1 4
output
9
input
5 11 1 1 1 15
output
-1
Note

In the first example Vasiliy can behave as follows. On the first and the second day he can prepare for the exam number 1 and pass it on the fifth day, prepare for the exam number 2 on the third day and pass it on the fourth day.

In the second example Vasiliy should prepare for the exam number 3 during the first four days and pass it on the fifth day. Then on the sixth day he should prepare for the exam number 2 and then pass it on the seventh day. After that he needs to prepare for the exam number 1 on the eighth day and pass it on the ninth day.

In the third example Vasiliy can't pass the only exam because he hasn't anough time to prepare for it.

思路:看了网上大神们的博客才知道这题竟然是要二分+贪心思想求解。。。

题目中要求说考试时间可以间断,那么如果在第i天考科目的d[i],那么前面i-1天中,至少要填入d[i]个用来复习,题目中还说某一天可以不考该科目用来复习其他科目,

贪心思想就是:如果y1和y2都可以考科目d[i],并且y2》=y1,那么我们就让d[i]在y2考,因为这样可以使y2前面剩余的空位数更多,可用来复习其他的科目,

y2>=y1的空位数;

//这里说一下比较巧妙的思想就是每次从后往前遍历:上面我们提到的如果y1,y2都可以考科目d[i],并且y1<=y2,我们就让他在y2考,所以我们这里就从后往前遍历,并标记,如果已经标记过了,就说明在后面考试了,前面可以用来复习其他的科目;

#include<stdio.h>
#include<string.h>
#define N 100010
int d[N],a[N],flag[N];
int n,m;
int check(int x)
{    int i;
     int sum=0;
    memset(flag,0,sizeof(flag));
    for(i=x;i>=1;i--)
    {   if(d[i]!=0&&flag[d[i]]==0)//如果被标记了,说明该考试已经考过,可以用来复习其他科目了;
           {  flag[d[i]]=1;
     sum+=a[d[i]];}
else if(sum!=0)
    sum--;
}
for(i=1;i<=m;i++)
 if(!flag[i])//有未被标记的就说明无法完成考试了;
           return 0;
    if(sum!=0)
      return 0;
      return 1;
}
int main()//二分法
{   int l,r,mid;
    scanf("%d%d",&n,&m);
    int i;
    for(i=1;i<=n;i++)
      scanf("%d",&d[i]);
    for(i=1;i<=m;i++)
      scanf("%d",&a[i]);
      l=1;
 r=n;
 while(l<r)
  {    mid=(l+r)/2;
    if(check(mid)==0)
       l=mid+1;
    else
       r=mid;
  } 
  if(check(l)==1)
   printf("%d",l);
   else
   printf("-1");
   return 0;
  
}


 


0 0
原创粉丝点击