您的位置:首页 > 其它

Codeforces 732D Exams【贪心+二分】

2017-03-06 14:39 197 查看
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 2
0 1 0 2 1 0 2
2 1


Output
5


Input
10 3
0 0 1 2 3 0 2 0 1 2
1 1 4


Output
9


Input
5 1
1 1 1 1 1
5


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. 

题目大意:

一共有N天(按照时间顺序给出),其中有M科目需要通过。

每个科目需要复习的天数是ai.

对应给出di为时间表,di==0的,可以选择复习任意一科,di!=0的,可以选择考di这一科,也可以选择复习任意一科。

问你能否通过所有考试,如果可以,输出最小天数。

思路:

1、对于天数来讲,时间越长,越有可能通过所有考试,那么这里就包含了一个单调性,我们可以二分天数,然后进行贪心处理。

2、对于当前枚举的天数mid.

我们要进行贪心判断:

①首先在从第一天到第mid天之内,必须要有di包含所有的科目,如果有一些科目没有出现过,那么这些科目是不能进行考试的,所以这种情况是不行的。

②贪心的去想,我们肯定考试越晚越好,所以我们取每一科最后出现的位子作为考这一科的时间。

③那么其他时间都是可以进行任意复习的时间,我们过程维护可以进行复习的天数还有多少天have.当遇到一个考试时间点,那么对应have-=需要复习这科的时间,如果have出现了负数的情况,那么对应增大时间,否则全程没遇到,就可以相应的减少时间了。

Ac代码:

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
int a[100050];
int ned[100050];
int last[100050];
int n,m;
int Slove(int mid)
{
int have=0;
memset(last,-1,sizeof(last));
for(int i=1;i<=mid;i++)
{
if(a[i]!=0)
{
last[a[i]]=i;
}
}
for(int i=1;i<=m;i++)if(last[i]==-1)return 0;
for(int i=1;i<=mid;i++)
{
if(a[i]==0)have++;
else
{
if(last[a[i]]==i)
{
if(have>=ned[a[i]])
{
have-=ned[a[i]];
}
else return 0;
}
else have++;
}
}
return 1;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=m;i++)scanf("%d",&ned[i]);
int ans=-1;
int l=1;
int r=n;
while(r-l>=0)
{
int mid=(l+r)/2;
if(Slove(mid)==1)
{
ans=mid;
r=mid-1;
}
else l=mid+1;
}
printf("%d\n",ans);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Codeforces 732D