Codeforces Round #377 (Div. 2) D 二分

来源:互联网 发布:过河进销存软件 编辑:程序博客网 时间:2024/04/29 13:31

题目传送门:http://codeforces.com/problemset/problem/732/D


题意:先给n天,di代表第i天可以通过第几门科目,再给m个数,si代表第i门科目需要准备几天。不管在哪一天都可以去考试或者准备考试。问能否通过考试,如果能,最少需要多少天才能通过考试。


思路:二分考试天数,check的时候用贪心的思想倒着check就行了


代码如下:

#include <iostream>#include <algorithm>#include <cstring>#include <stdio.h>#include <string>#include <cmath>#include <queue>#include <set>#include <map>#include <stack>#include <bitset>#include <cstdlib>using namespace std;#define   lson          l,m,rt<<1#define   rson          m+1,r,rt<<1|1#define   ll            long long#define   ull           unsigned long long#define   mem(n,v)      memset(n,v,sizeof(n))#define   MAX           100005#define   MAXN          10005#define   PI            3.1415926#define   E             2.718281828459#define   opnin         freopen("text.in.txt","r",stdin)#define   opnout        freopen("text.out.txt","w",stdout)#define   clsin         fclose(stdin)#define   clsout        fclose(stdout)#define   haha1         cout << "haha1"<< endl#define   haha2         cout << "haha2"<< endl#define   haha3         cout << "haha3"<< endlconst int    INF    =   0x3f3f3f3f;const ll     INFF   =   0x3f3f3f3f3f3f3f3f;const double pi     =   3.141592653589793;const double inf    =   1e18;const double eps    =   1e-8;const ll     mod    =   1e18;const ull    mx     =   133333331;/**************************************************************************/int day[MAX];int sub[MAX];int vis[MAX];bool check(int n,int m){    int cnt = 0;    int sum = n;    for(int i=n;i>=1;i--){//        cout << "sum: " << sum << endl;        if(cnt == m) break;        if(day[i] && !vis[day[i]]){            if(sum <= i-1) sum--;            else sum = i-1;            if(sum >= sub[day[i]]){                sum -= sub[day[i]];                cnt++;                vis[day[i]] = 1;            }            else break;        }    }    return cnt == m;}int main(){    int n,m;    cin >> n >> m;    for(int i=1;i<=n;i++)        scanf("%d",&day[i]);    for(int i=1;i<=m;i++)        scanf("%d",&sub[i]);    int l = 1,r = n+1;    while(l< r){//        cout << l << ' ' << r << endl;        mem(vis,0);        int mid = (l + r) >> 1;        if(check(mid,m)) r = mid;        else l = mid + 1;    }    if(l == n+1) cout << "-1" << endl;    else cout << l << endl;    return 0;}


0 0
原创粉丝点击