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;
    }
    
  • 相关阅读:
    phpcms二级菜单
    html5 audio JavaScript 点击播放暂停
    jquery获取type=radio属性的值
    github push 出错:fatal: Authentication failed for 'https://github.com/ ..的解决
    win10远程桌面出现身份验证错误的解决方法
    谷歌和火狐浏览器清除缓存快捷键
    JavaScript的动画
    随机颜色的函数
    JQuery写的一个常见的banner
    网页点击跳转到微信页面
  • 原文地址:https://www.cnblogs.com/s1124yy/p/6144694.html
Copyright © 2011-2022 走看看