一道二分题,比赛的时候是用贪心水过了,数据太弱哈哈哈!!
只要写一个check函数配合二分查找答案范围就好了~
#include<bits/stdc++.h>
using namespace std;
int num[100005],d[100005],n,m,vis[100005];
long long sum;
int check(int x) {
memset(vis,0,sizeof(vis));
int cost = 0;
if(x < sum+m)
return 0;
for(int i = x;i >= 1;i--) {
if(num[i] && !vis[num[i]] && i - cost - 1 < d[num[i]]) {
return 0;
}
if(num[i] && !vis[num[i]] && i - cost - 1 >= d[num[i]]) {
cost += d[num[i]];
vis[num[i]] = 1;
}
else if(cost)
cost--;
}
for(int i = 1;i <= m;i++)
if(!vis[i])
return 0;
return 1;
}
int main() {
while(scanf("%d%d",&n,&m) != EOF) {
for(int i = 1;i <= n;i++)
scanf("%d",&num[i]);
sum = 0;
for(int i = 1;i <= m;i++) {
scanf("%d",&d[i]);
sum += d[i];
}
int l = 0,r = n+1,mid;
while(l+1 < r) {
mid = (l+r)>>1;
if(check(mid)) r = mid;
else l = mid;
}
if(check(l))
printf("%d\n",l);
else if(check(l+1) && l+1 <= n)
printf("%d\n",l+1);
else
printf("-1\n");
}
}
比较难得的做出了D题,室友用的二分还因为边界问题挂了,不说了,继续多刷题吧,加油!