Codeforces Round #377 (Div. 2) D. Exams 贪心 + 简单模拟

http://codeforces.com/contest/732/problem/D

这题我发现很多人用二分答案,但是是不用的。

我们统计一个数值all表示要准备考试的所有日子和。+m(这些时间用来考试)

那么这个all值就是理想的最小值。然后去前all个数找,贪心地复习最小的科目,然后有的考试的话,就优先考试。

如果经过这all天,复习完了(这个是肯定得),但是只是因为时间分配不好,导致没得考试(数据导致没得考试)

那么就暴力枚举后面的[all + 1, n]。有得考试就去考试,刚好考完就直接输出i就可以了。

 

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 1e5 + 20;
int a[maxn];
int day[maxn];
void work() {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }
    LL all = m;
    for (int i = 1; i <= m; ++i) {
        cin >> day[i];
        all += day[i];
    }
    sort(day + 1, day + 1 + m);
    int lenday = 1;
    int now = 0;
    if (n < all) {
        cout << "-1" << endl;
        return;
    }
    for (int i = 1; i <= all; ++i) {
        if (a[i] == 0) {
            day[lenday]--;
            if (day[lenday] == 0) {
                now++;
                lenday++;
            }
        } else {
            if (now) now--;
            else {
                day[lenday]--;
                if (day[lenday] == 0) {
                    now++;
                    lenday++;
                }
            }
        }
    }
    if (now == 0) {
        cout << all << endl;
        return;
    }
    for (int i = all + 1; i <= n; ++i) {
        if (a[i] == 0) {
            continue;
        } else {
            now--;
            if (now == 0) {
                cout << i << endl;
                return;
            }
        }

    }
    cout << "-1" << endl;
}

int main() {
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    work();
    return 0;
}
View Code

 

posted on 2016-10-18 10:00  stupid_one  阅读(233)  评论(0编辑  收藏  举报

导航