zoukankan      html  css  js  c++  java
  • Codeforces Round #377 (Div. 2) D. Exams(二分答案)

    D. Exams

    Problem Description:

    Vasiliy has an exam period which will continue for n days. He has to pass exams on m subjects. Subjects are numbered from 1 to m.

    About every day we know exam for which one of m subjects can be passed on that day. Perhaps, some day you can't pass any exam. It is not allowed to pass more than one exam on any day.

    On each day Vasiliy can either pass the exam of that day (it takes the whole day) or prepare all day for some exam or have a rest.

    About each subject Vasiliy know a number ai — the number of days he should prepare to pass the exam number i. Vasiliy can switch subjects while preparing for exams, it is not necessary to prepare continuously during ai days for the exam number i. He can mix the order of preparation for exams in any way.

    Your task is to determine the minimum number of days in which Vasiliy can pass all exams, or determine that it is impossible. Each exam should be passed exactly one time.

    Input:

    The first line contains two integers n and m (1 ≤ n, m ≤ 105) — the number of days in the exam period and the number of subjects.

    The second line contains n integers d1, d2, ..., dn (0 ≤ di ≤ m), where di is the number of subject, the exam of which can be passed on the day number i. If di equals 0, it is not allowed to pass any exams on the day number i.

    The third line contains m positive integers a1, a2, ..., am (1 ≤ ai ≤ 105), where ai is the number of days that are needed to prepare before passing the exam on the subject i.

    Output:

    Print one integer — the minimum number of days in which Vasiliy can pass all exams. If it is impossible, print -1.

    Sample Input:

    7 2
    0 1 0 2 1 0 2
    2 1

    Sample Output:

    5

    这题是二分答案,一看见1e5,就可以想到二分了 二分时while()中一定要是小于等于啊

    【题目链接】D. Exams

    【题目类型】二分答案

    &题解:

    这题首先你要发现一个可以(O(n))判断是否可行的方法,想一想,并不难: 倒着推,把最后一次考试的时间全部记下来,之后正着推,判断时间是否够用就好了
    之后就是二分的部分了,还是那句话二分时while()中一定要是小于等于啊

    【时间复杂度】(O(nlogn))

    &代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int INF = 0x3f3f3f3f;
    #define cle(a,val) memset(a,(val),sizeof(a))
    #define SI(N) scanf("%d",&(N))
    #define SII(N,M) scanf("%d %d",&(N),&(M))
    #define SIII(N,M,K) scanf("%d %d %d",&(N),&(M),&(K))
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define red(i,a,b) for(int i=(a);i>=(b);i--)
    const ll LINF = 0x3f3f3f3f3f3f3f3f;
    #define PU(x) cout<<#x<<endl;
    #define PI(A) cout<<(A)<<endl;
    #define DG(x) cout<<#x<<"="<<(x)<<endl;
    #define DGG(x,y) cout<<#x<<"="<<(x)<<" "<<#y<<"="<<(y)<<endl;
    #define DGGG(x,y,z) cout<<#x<<"="<<(x)<<" "<<#y<<"="<<(y)<<" "<<#z<<"="<<(z)<<endl;
    #define PIar(a,n) rep(i,0,n-1)cout<<a[i]<<" ";PU()
    #define PIarr(a,n,m) rep(aa,0,n-1){rep(bb,0,m-1)cout<<a[aa][bb]<<" ";PU()}
    typedef pair<int, int> pii;
    #define fi first
    #define se second
    #define pb push_back
    #define mp make_pair
    #define sz(x) int(x.size())
    #define all(x) x.begin(),x.end()
    const double EPS = 1e-9 ;
    /*  ////////////////////////   C o d i n g  S p a c e   ////////////////////////  */
    const int maxn = (int)1e5 + 9 ;
    int n, m, d[maxn], a[maxn];
    set<int> sei;
    vector<int> vei;
    bool ok(int x) {
    	sei.clear();
    	vei.clear();
    	for (; x >= 1; x--) if (d[x] && !sei.count(d[x])) {
    			sei.insert(d[x]);
    			vei.pb(x);
    		}
    	if (sei.size() != m) { return false; }
    	ll sum=0;
    	for (int i = sz(vei) - 1; i >= 0; i--) {
    		if (vei[i]>sum+a[d[vei[i]]]) sum+=a[d[vei[i]]]+1;
    		else return false;
    	}
    	return true;
    }
    void Solve() {
    	while (cin >> n >> m) {
    		rep(i, 1, n) cin >> d[i];
    		rep(i, 1, m) cin >> a[i];
    		int l = 0, r = n + 1,m;
    		//二分这一定要是l<=r  不要忘了是<=
    		while(l<=r) {
    			m=l+r>>1;
    			//这保证的是一开一闭区间 也就是[ , ) 或 ( , ]
    			if (ok(m)) r=m-1;
    			else l=m+1;
    		}
    		if (l>n||l<1) l=-1;
    		PI(l)
    		//可以看一下他们3个的区别
    //		DGGG(l,r,m)
    	}
    }
    int main() {
    #ifndef ONLINE_JUDGE
    	freopen("1.in", "r", stdin);
    #endif
    	iostream::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    	Solve();
    	return 0;
    }
    
  • 相关阅读:
    每周总结15
    第二阶段Day02
    第二阶段Day01
    假期学习记录03(高德地图错误码为7:key鉴权错误)
    假期学习记录02(高德地图关于开发版和调试版sha值)
    假期学习记录01(地图显示和基本的配置)
    android获取当前步数
    android实现轮播图(从互联网上寻找图片)
    android中gps的应用
    互联网营销精准决策项目总结
  • 原文地址:https://www.cnblogs.com/s1124yy/p/6144694.html
Copyright © 2011-2022 走看看