贪心判定
考试复习时间可以间断,则如果在第i天考科目day[i],相当于在前i-1天中,要任意填入day[i]个(前i-1天要有day[i]个空位)
贪心:若在x天完成全部考试 第y1和第y2天都能考同一个科目&&y2>y1
显然选择在靠后的第y2天考该科目 y2的空位数>=y1的空位数
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
typedef long long ll;
const int N=1e5+20;
int day[N];// day[i] 第i天的内容 exam or whatever
int a[N];//a[i] i'th sub复习时间
int n,m;
int vis[N];
bool check(int x)//判定在x天内能否完成m场考试
{
//考试复习时间可以间断,则如果在第i天考科目day[i],相当于在前i-1天中,要任意填入day[i]个(前i-1天要有day[i]个空位)
//贪心:若在x天完成全部考试 第y1和第y2天都能考同一个科目&&y2>y1
//显然选择在靠后的第y2天考该科目 y2的空位数>=y1的空位数
memset(vis,0,sizeof(vis));
int sub=0;
int flag=0;
int need=0;//需要的空位
for(int i=x;i>=1;i--)
{
if(day[i]&&!vis[day[i]])
{
sub++;
need+=a[day[i]];
vis[day[i]]=1;
continue;
}
if(need)//不需要空位时,不能复习
{
need--;
}
}
// cout<<x<<" "<<sub<<" "<<need<<endl;
return sub==m&&need<=0;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>day[i];
for(int i=1;i<=m;i++)
cin>>a[i];
int l=0,r=n;
int ans=-1;
while(l<=r)//二分求最值
{
int mid=(l+r)/2;
if(check(mid))
{
ans=mid;
r=mid-1;
}
else
{
l=mid+1;
}
}
cout<<ans<<endl;
return 0;
}