[USACO Mar07] 月度花费
Farmer John是一个令人惊讶的会计学天才,他已经明白了他可能会花光他的钱,这些钱本来是要维持农场每个月的正常运转的。他已经计算了他以后 N(1<=N<=100,000)个工作日中每一天的花费moneyi(1<=moneyi<=10,000),他想要为他连续 的M(1<=M<=N)个被叫做“清算月”的结帐时期做一个预算,每一个“清算月”包含一个工作日或更多连续的工作日,每一个工作日都仅被包 含在一个“清算月”当中。
FJ的目标是安排这些“清算月”,使得每个清算月的花费中最大的那个花费达到最小,从而来决定他的月度支出限制。
输入
第一行:两个用空格隔开的整数:N和M 第2..N+1行:第i+1行包含FJ在他的第i个工作日的花费
输出
第一行:能够维持每个月农场正常运转的钱数
样例输入
7 5 100 400 300 100 500 101 400
样例输出
500
输入细节
这里有7个工作日来被5个“清算月”划分。他花费100,400,100,500,101,和400元在他的每个工作日。
输出细节
如果FJ安排他的月度预算,他将把前两天划分在一个月中,把第三天、第四天划分在一个月当中,最后的三个工作日各自在一个月当中,所以他一个月最多花费500元,其他的方法总是得出一个较大的结果。
100 400 300 100 500 101 400 每天花费 ---1--- ---2--- -3- -4- -5- 月度标号 500 400 500 101 400 月度花费
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /* 2 COGS 随机水题 3 简单二分一下 4 注意二分出来的数可能比输入的数小 5 */ 6 #include <ctype.h> 7 #include <cstdio> 8 9 const int MAXN=100010; 10 11 inline void read(int&x) { 12 register char c=getchar(); 13 for(x=0;!isdigit(c);c=getchar()); 14 for(;isdigit(c);x=x*10+c-48,c=getchar()); 15 } 16 17 int n,k; 18 19 int a[MAXN]; 20 21 inline bool check(int x) { 22 int t=0,tot=1; 23 for(int i=1;i<=n;++i) { 24 if(a[i]>x) return false; 25 if(t+a[i]<=x) t+=a[i]; 26 else t=a[i],++tot; 27 } 28 if(tot<=k) return true; 29 else return false; 30 } 31 32 int hh() { 33 freopen("expense.in","r",stdin); 34 freopen("expense.out","w",stdout); 35 int l=0,r=0; 36 read(n);read(k); 37 for(int i=1;i<=n;++i) read(a[i]),r+=a[i]; 38 while(l+1<r) { 39 int mid=(l+r)>>1; 40 if(check(mid)) r=mid; 41 else l=mid; 42 } 43 printf("%d\n",r); 44 return 0; 45 } 46 47 int sb=hh(); 48 int main() {;}
作者:乌鸦坐飞机
出处:http://www.cnblogs.com/whistle13326/
新的风暴已经出现
怎么能够停止不前
穿越时空 竭尽全力
我会来到你身边
微笑面对危险
梦想成真不会遥远
鼓起勇气 坚定向前
奇迹一定会出现