【题目描述】:
聪哥在暑假参加了打零工的活动,这个活动分为n个工作日,每个工作日的工资为Vi。有m个结算工钱的时间,聪哥可以自由安排这些时间,也就是说什么时候拿钱,老板说的不算,聪哥才有发言权!(因为聪哥是土豪,他是老板的老板)
聪哥不喜欢身上一次性有太多的钱,于是他想安排一下拿钱的时间,使他一次性拿的钱中最大的最小。(最后一天一定要领钱)
【输入描述】:
第一行 2个数 n,m
接下来n行,每行一个数,代表Vi。
【输出描述】:
最小的最大钱数。
【样例输入】:
7 5
100
400
300
100
500
101
400
【样例输出】:
500
【样例说明】:
100 400//300 100//500//101//400//
“//”表示老大要去拿钱。
【时间限制、数据范围及描述】:
时间:1s 空间:256M
20% : 1<=n<=20
另20%:1<=n<=50, Vi的和不超过1000
100%: 1<=n<=100,000, m<=n, Vi<=10,000
1 #include "bits/stdc++.h" 2 using namespace std; 3 typedef long long LL; 4 const int MAX=100005; 5 int n,m; 6 LL a[MAX]; 7 LL low,high,mid; 8 void init(){ 9 int i,j; 10 scanf("%d%d",&n,&m); 11 for (i=1;i<=n;i++){ 12 scanf("%lld",a+i); 13 low=max(low,a[i]); 14 high+=a[i]; 15 } 16 } 17 bool feasible(LL x){ 18 int i,j; 19 LL zt=0,an=0; 20 for (i=1;i<=n;i++){ 21 if (a[i]+zt>x){ 22 zt=a[i]; 23 an++; 24 } 25 else 26 zt+=a[i]; 27 } 28 return (an>=m); 29 } 30 int main(){ 31 init();int i,j; 32 while (low<=high){ 33 mid=(low+high)>>1; 34 if (feasible(mid)) 35 low=mid+1; 36 else 37 high=mid-1; 38 } 39 printf("%d",low); 40 return 0; 41 }