• 二分


    二分答案

    推荐

      二分一般直接二分答案mid,然后利用题目中的某个限制来检验这个mid是否是正确。

    不正确就接着分。

    一般框架:

    int l, r;
    
    while (l <= r) {
    	int mid = (l + r) / 2;
    	if (check(mid)) 答案就是mid;
    	else 根据题意,l = mid + 1 或者 r = mid - 1; 
    }
    

    1.跳石头(noip 2015 D2T1)

      代码:

    #include <cstdio>
    
    const int MAXN = 5e4 + 7;
    
    int s, n, m, a[MAXN];
    
    int check(int x) {
    	int last = 0, re = 0;
    	for (int i = 1; i <= n + 1; i++) 
    		if (a[i] - last < x) re++;
    		else last = a[i];
    	
    	return re;
    }
    
    int main() {
    	scanf("%d%d%d", &s, &n, &m);
    	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
    	a[n + 1] = s;
    	
    	int l = 1, r = s, ans = 0;
    	while (l <= r) {
    		int mid = (l + r) >> 1;
    		int f = check(mid);
    //		printf("when mid = %d, f = %d
    ", mid, f);
    		if (f <= m) l = mid + 1, ans = mid;
    		else r = mid - 1; 
    	}
    	
    	printf("%d
    ", ans);
    	
    	return 0;
    } 
    

         

    2、聪明的质检员(noip 2011)

    对于10% 的数据,有 1 ≤n ,m≤10;

    对于30% 的数据,有 1 ≤n ,m≤500 ;

    对于50% 的数据,有 1 ≤n ,m≤5,000;

    对于70% 的数据,有 1 ≤n ,m≤10,000 ;

    对于100%的数据,有 1 ≤n ,m≤200,000,0 < wi, vi≤10^6,0 < S≤10^12,1 ≤Li ≤Ri ≤n 。

        首先,单纯的二分。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #define ll long long
    
    const int MAXN = 200007;
    
    ll n, m, s, v[MAXN], w[MAXN], q[MAXN][2], rez = 1e13, retn;
    
    ll check(ll x) {
    	ll ans = 0, f = 0, retn = 0;
    	for (ll i = 1; i <= m; i++) {
    		f = 0, ans = 0;
    		for (ll j = q[i][0]; j <= q[i][1]; j++) 
    			if (w[j] >= x) ans += v[j], f++;	
    		retn += ans * f;
    	}
    	
    	retn = s - retn;
    	return retn;
    }
    
    int main() {
    	scanf("%lld%lld%lld", &n, &m, &s);
    	
    	for (int i = 1; i <= n; i++) scanf("%lld%lld", &w[i], &v[i]);
    	for (int i = 1; i <= m; i++) scanf("%lld%lld", &q[i][0], &q[i][1]);
    	
    	int l = 0, r = 1e6 + 1;
    	while (l <= r) {
    		ll mid = (l + r) / 2;
    		ll p = check(mid);
    		if (p > 0) {
    			if (p < rez) rez = p;
    			r = mid - 1;
    		} else if (!p) {
    			printf("0
    ");
    			return 0;
    		} else {
    			p = -p;
    			if (p < rez) rez = p;
    			l = mid + 1;
    		}
    //		printf("%lld
    ", p);
    	}
    	
    	printf("%lld
    ", rez);
    	
    	return 0;
    }
    

       check() 里是 n^2 的,肯定是A不了的,只过了50%的数据。

      于是我们来想一想优化。

      前缀和优化!

     

      

  • 相关阅读:
    垃圾回收app冲击(一)
    本篇看似是一篇拍马屁的博客!但是真情实感!
    搜索建议
    冲击团队项目需求分析
    疫情分析冲击(五)
    疫情分析冲击(四)
    疫情分析冲击(三)
    疫情分析冲击(二)
    垃圾分类网站
    Android学习——singleInstance
  • 原文地址:https://www.cnblogs.com/ExileValley/p/7792927.html
Copyright © 2020-2023  润新知