题意是给你一个序列,你可以将其分为M段,并且要求分出的每个区间和的最大值最小,问这个最小值是多少。
分析:我们应该想到的是这个问法应该是具有二段性的,那么我们如何去二分呢?事实上我们直接二分答案即可,容易想到如果和越大,那么被分的区间数量就越少,要刚好分为M段,我们只需要看每次分出的段数量是否小于等于M即可,具体代码如下:
#include <iostream> using namespace std; const int N = 100010; int w[N], n, m, l, r; bool check(int mid){ int cnt = 1, s = 0; for(int i=1; i<=n; i++){ // if(w[i]>mid) return false; if(s+w[i]>mid)cnt++, s=0; s+=w[i]; } return cnt<=m;//如果小于等于m,那么答案应该在右边 } int main(void){ cin>>n>>m; for(int i=1; i<=n; i++){ cin>>w[i]; l=max(l, w[i]); r+=w[i]; } while(l<r){ int mid = l+r>>1; if(check(mid))r=mid;//如果小于等于m,那么答案应该在右边 else l=mid+1; } cout<<l<<endl; return 0; }