上次写某道findpath的时候,没有写个二分答案没有过,之后就发现自己貌似一开始学分治那一块的时候就没有把二分学好....就打算重新回顾一下
这道题还算水,就是太久没有写模拟wa了3次....对自己简直是无语,倍感基础弱没话说..
不过算是清楚二分的原理,二分还算是比较好理解的了,可以说是把一个很大的东西不停的分成二份...
就最近学的来看,基本上都会用到这样的代码:(大概是这样)
int l=0,r=max,mid; while(){ mid=(l+r)>>1; if (mid.....) l=....; else r=....; }
就这一道题来说的话,就是二分答案+模拟
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
任务分配 【问题描述】 图书馆按顺序排列有N本书需要维护,每本书的总页数不相同。现有M位员工。可以给每个员工分配连续的一段书籍,让他进行维护。现在的问题是,怎么样分配,工作任务最重(需要维护的页数最多)的人维护的页数尽量少。 【输入格式】 第一行两个数,N、M。接下来N行,每行一个整数,表示一本书的页数。 【输出格式】 任务最重的人最少需要维护的页数。 【输入样例】 5 3 3 2 4 1 5 【输出样例】 5 【数据范围】 20%数据:N<=1000 30%数据:N<=10000 100%数据::N<=100000,M<=N。一本书的页数最多10000。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<cstdio> #include<cstring> using namespace std; int a[100001],n,m; bool check(int x){ int now=x,tot=0; for (int i=0;i<n;i++){ if (x<a[i]) return false; if (now-a[i]<0){ now=x; tot++; now-=a[i]; if (tot==m) return false; } else now-=a[i]; } return true; } int main(){ int i,j,s,t,tot=0; freopen("book.in","r",stdin);freopen("book.out","w",stdout); scanf("%d%d",&n,&m); for (i=0;i<n;i++){ scanf("%d",&a[i]); tot+=a[i]; } int r=tot,l=0; while (l<=r){ int mid=(l+r)>>1; if(check(mid)) r=mid-1; else l=mid+1; } printf("%d",l); return 0; }
哦。。对了,还有自己代码的习惯不太好,注意一下嗯