码迷,mamicode.com
首页 > 其他好文 > 详细

二分例题简单说明

时间:2019-08-10 09:44:18      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:bit   clu   code   namespace   can   problem   ret   输出   例题   

第一题 愤怒的牛

这道题绝对是二分答案的入门题,简单易懂。

但是针对 L,R,mid 的这三个变量,我还是思考了很长时间。

所以这也要说一下

L 是满足条件的最小值

mid=(L+R)/2;

R 是满足条件的最大值

这道题让求最大的最小,所以当然是输出 R。

第二题 Best Cow Fences

这道题luogu上也有: 平均数

这道题最开始感觉真的好难,我想了好几种,都是 N^2*logN 的,显然过不了。

因为为了满足 子段长度>=k这个条件,我用的是N^2的,所以要想一种更优秀的方法

!!给下面划重点 !!

先用前缀和处理一下,并且每一项在加进去之前都要-mid。

要求>=k,①只需要满足一次即可

②只要>=0就行

根据①,我们找到一次就 break;

根据②,我们模拟前缀和 1~i-k 的最小值就好。

所以不用模拟开头,少一个N

整体算法变为N*logN

CODE:

#include<bits/stdc++.h>
using namespace std;
int n,m,L,R,ans;
long long s[100005],a[100005],Max;
bool check(){
    long long last=0;
    for(int i=m;i<=n;i++){
        if(s[i]-last>=0) return true;
        last=min(last,s[i-m+1]);
    }
    return false;   
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        a[i]*=1000;
        Max=max(a[i],Max);
    }
    L=0,R=Max;
    long long mid;
    while(L<=R){
        mid=(L+R)/2;    
        for(int i=1;i<=n;i++) s[i]=s[i-1]+a[i]-mid;
        if(check()) L=mid+1;
        else R=mid-1; 
    }
    cout<<R;
    return 0;
}

二分例题简单说明

标签:bit   clu   code   namespace   can   problem   ret   输出   例题   

原文地址:https://www.cnblogs.com/fashpoint/p/11330464.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!