和这道题一样了:
Description
聪哥在暑假参加了打零工的活动,这个活动分为n个工作日,每个工作日的工资为Vi。有m个结算工钱的时间,聪哥可以自由安排这些时间,也就是说什么时候拿钱,老板说的不算,聪哥才有发言权!(因为聪哥是土豪,他是老板的老板)
聪哥不喜欢身上一次性有太多的钱,于是他想安排一下拿钱的时间,使他一次性拿的钱中最大的最小。(最后一天一定要领钱)
Input
第一行 2个数 n,m
接下来n行,每行一个数,代表Vi.
Output
最小的最大钱数。
样例说明
100 400//300 100//500//101//400//
“//”表示老大要去拿钱。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>using namespace std;
int n,m;
int a[100000+5];
bool C(int x)
{int cnt=0;//划分次数int s=0;for(int i=0;i<n;i++){if(a[i]>x)return false;s+=a[i];if(s>x){cnt++;s=a[i];}}cnt++;//最后划分if(cnt<=m)return true;//可行解else return false;}
int main()
{cin>>n>>m;int sum=0;for(int i=0;i<n;i++){scanf("%d",&a[i]);sum+=a[i];}int lb=0;int ub=sum;//不能放宽。m=1的时候ub=sumwhile(ub-lb>1){int mid=(ub+lb)/2; if(C(mid))ub=mid;//最小化可行解else lb=mid;}cout<<ub;
}