WHYZOJ-#60 工资(二分)

【题目描述】:

聪哥在暑假参加了打零工的活动,这个活动分为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 }
未来是什么样,未来会发生什么,谁也不知道。 但是我知道, 起码从今天开始努力, 肯定比从明天开始努力, 要快一天实现梦想。 千里之行,始于足下! ——《那年那兔那些事儿》
原文地址:https://www.cnblogs.com/keximeiruguo/p/7309771.html