思路:二分枚举答案,在限定时间内判断这个时间能否完成。贪心策略是尽量晚的安排每个考试。
AC代码:
#include <cstdio>
#include <cmath>
#include <cctype>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 1e5 + 5;
int n, m, sum;
int d[maxn], a[maxn];
int vis[maxn];
bool check(int lim) {
memset(vis, 0, sizeof(vis));
int w = 0, cnt = 0;
for(int i = lim; i >= 1; --i) {
int u = d[i];
if(u && !vis[u]) {
++cnt;
vis[u] = 1;
w += a[u]; //需要a[u]天准备考试
}
else w = max(0, w-1);
}
if(cnt < m || w > 0) return false;
return true;
}
int main() {
while(scanf("%d%d", &n, &m) == 2) {
for(int i = 1; i <= n; ++i) scanf("%d", &d[i]);
sum = 0;
for(int i = 1; i <= m; ++i) {
scanf("%d", &a[i]);
}
int x = 0, y = n+1;
while(x < y) {
int mid = (x + y) / 2;
if(check(mid)) y = mid;
else x = mid+1;
}
if(y <= n) printf("%d\n", y);
else printf("-1\n");
}
return 0;
}
如有不当之处欢迎指出!