codeforces 732D (二分 贪心)

来源:互联网 发布:谷歌拍照软件 编辑:程序博客网 时间:2024/05/29 07:45

题目链接:点击这里

题意:给出n天,以及每天能考的科目,给出每个科目需要备考的天数。每一天可以选择备考某一门科目或者考试通过某一门科目(备考天数足够)。求通过所有科目的最少天数。

二分天数mid,然后对于前mid天贪心check。具体就是从mid往前扫,如果有没有考试过的科目就选择在这一天考,否则用来备考。
最后从前往后依次判断备考是否足够即可。

#include <cstdio>#include <cmath>#include <algorithm>#include <iostream>#include <vector>#include <cstring>using namespace std;#define maxn 100005int a[maxn], d[maxn];int n, m;int pos[maxn];bool vis[maxn];bool ok (int x) {    memset (pos, 0, sizeof pos);    memset (vis, 0, sizeof vis);    for (int i = x; i >= 1; i--) {        if (d[i] != 0 && !vis[d[i]]) {            pos[i] = d[i];//第i天学d[i]            vis[d[i]] = 1;        }    }    int pre = 0;    for (int i = 1; i <= x; i++) {        if (!pos[i]) pre++;        else {            if (a[pos[i]] > pre) return 0;            else pre -= a[pos[i]];        }    }    for (int i = 1; i <= m; i++) if (!vis[i]) return 0;    return 1;}int main () {    ios::sync_with_stdio (0);    cin >> n >> m;    for (int i = 1; i <= n; i++) cin >> d[i];    for (int i = 1; i <= m; i++) cin >> a[i];    int l = 1, r = n;    while (r-l > 1) {        int mid = (r+l)>>1;        if (ok (mid)) r = mid;        else l = mid;    }    if (ok (l)) cout << l << endl;    else if (ok (r)) cout << r << endl;    else cout << -1 << endl;    return 0;}
0 0
原创粉丝点击