06:月度开销

题目链接:http://noi.openjudge.cn/ch0111/06/

总时间限制: 1000ms 内存限制: 65536kB
描述
  农夫约翰是一个精明的会计师。他意识到自己可能没有足够的钱来维持农场的运转了。他计算出并记录下了接下来 N (1 ≤ N ≤ 100,000) 天里每天需要的开销。

  约翰打算为连续的M (1 ≤ M ≤ N) 个财政周期创建预算案,他把一个财政周期命名为fajo月。每个fajo月包含一天或连续的多天,每天被恰好包含在一个fajo月里。

  约翰的目标是合理安排每个fajo月包含的天数,使得开销最多的fajo月的开销尽可能少。

输入
  第一行包含两个整数N,M,用单个空格隔开。
  接下来N行,每行包含一个1到10000之间的整数,按顺序给出接下来N天里每天的开销。
输出
  一个整数,即最大月度开销的最小值。

样例输入
7 5
100
400
300
100
500
101
400
样例输出
500
输入输出样例说明
  若约翰将前两天作为一个月,第三、四两天作为一个月,最后三天各自作为一个月,则最大月度开销为500。其他任何分配方案都会比这个值更大。

先看AC代码:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 int check(long *a,long N,long long mid,long M); 5 int main()
 6 {
 7     long N,M;
 8     long *a=NULL,i;
 9     long long left=0,right=0,mid=0;
10     int res;
11     12     scanf("%ld%ld",&N,&M);
13     a=(long*)malloc(N*sizeof(long));
14     memset(a,0,N);
15     for(i=0;i<N;i++)
16     {
17         scanf("%ld",&a[i]);
18         if(a[i]>left) left=a[i];
19         right=right+a[i];
20     }
21
22     while(left<right)
23     {
24         mid=left+(right-left)/2;
25         res=check(a,N,mid,M);
26         if(res==1) right=mid;
27         else left=mid+1;
28     }
29     printf("%lld\n",left);
30     return 0;
31 }
32
33 //假设最大月开销为mid,统计需要分成多少个月.然后看月的个数是否太多或太少
34 int check(long *a,long N,long long mid,long M)
35 {
36     long count=1,i,temp=0;
37     for(i=0;i<N;i++)
38     {
39         if(temp+a[i]<=mid) temp=temp+a[i];//把第i天归入到当前第count月
40         else if(a[i]<=mid)//可以独立成一个月
41         {
42             count++;//开始一个新的月
43             temp=a[i];
44             if(count>M) return -1;//最大月开销太小,导致分的组太多了。
45         }
46         else return -1;//最大月开销mid太小了,导致某些开销比较大的天单独构成一个月都不行。
47     }
48     if(count>M) return -1;
49     else if(count<=M) return 1;//最大月开销mid太大了,导致分的组太少了
50 }

思路说明:

题目的意思一定要理解清楚!!!“合理安排每个fajo月包含的天数,使得开销最多的fajo月的开销尽可能少。”   “输出一个整数,即最大月度开销的最小值。”

就是把所有天划分为若干个段,先求出每个段里面的数字之和,然后统计各段累加和的最大值,这个值要尽可能小。现在要找的就是这个“累加和的最大值”   最小可以是多少。

首先,这个题目应该二分,因为解的区间是可以明确的,可以对该区间进行二分求的真正的解。

假设二分的区间left~right,其中left是n天开销中最大的那一个数字,right是n天开销的总和。  (设想一个极限情况,要使得每一个月开销尽量小,那么每一天都单独做一个月就好啦,于是这个时候的月开销最大值就是n天中每天开销最大的值,所以left可以取max(a1,......,an)。    再设想另一种极限情况,把所有天合并在一起组成一个月,那么这个时候月开销最大值就是sum(a1,a2,......,an),所以right取值就是n天的累加和。)

需要注意的一个地方是二分循环部分的代码:

1     while(left<right)
2     {
3         mid=left+(right-left)/2;
4         res=check(a,N,mid,M);
5         if(res==1) right=mid;
6         else left=mid+1;
7     }
8     printf("%lld\n",left);

其中left=mid+1这里必须加上1,否则可能会死循环的。

另外,输出值是left。这个地方也要特别注意。(请自己脑补为何是left吧)

关于子函数check(),嗯代码注释讲的很清晰,不说了。

时间: 2024-08-16 18:05:34

06:月度开销的相关文章

月度开销

月度开销 06:月度开销 总时间限制:  1000ms 内存限制:  65536kB 描述 农夫约翰是一个精明的会计师.他意识到自己可能没有足够的钱来维持农场的运转了.他计算出并记录下了接下来 N (1 ≤ N ≤ 100,000) 天里每天需要的开销. 约翰打算为连续的M (1 ≤ M ≤ N) 个财政周期创建预算案,他把一个财政周期命名为fajo月.每个fajo月包含一天或连续的多天,每天被恰好包含在一个fajo月里. 约翰的目标是合理安排每个fajo月包含的天数,使得开销最多的fajo月的

bzoj 1639 月度开销

escription Farmer John是一个令人惊讶的会计学天才,他已经明白了他可能会花光他的钱,这些钱本来是要维持农场每个月的正常运转的.他已经计算了他以后 N(1<=N<=100,000)个工作日中每一天的花费moneyi(1<=moneyi<=10,000),他想要为他连续 的M(1<=M<=N)个被叫做"清算月"的结帐时期做一个预算,每一个"清算月"包含一个工作日或更多连续的工作日,每一个工作日都仅被包 含在一个&q

整理小朋友在noi.openjudge上的作业(1)

NOI(题库正在建设中,做题纪录有可能会被删除,请注意) 第一章的统计放前面 1 编程基础之输入输出 10 0 0% 最基础有空补刷 2 编程基础之变量定义.赋值及转换 10 0 0% 最基础有空补刷 3 编程基础之算术表达式与顺序执行 20 0 0% 最基础有空补刷 4 编程基础之逻辑表达式与条件分支 21 0 0% 最基础有空补刷 5 编程基础之循环控制 45 10 22% 最基础有空补刷 6 编程基础之一维数组 15 5 33% 最基础有空补刷 7 编程基础之字符串 35 0 0% 有必要

二分 题目 压缩打包 Special Judge? 不不不 当然不是

http://noi.openjudge.cn/ch0111/ No 题目 分数 01 查找最接近的元素 10 3176 02 二分法求函数的零点 10 2181 03 矩形分割 10 1420 04 网线主管 10 1648 05 派 10 1581 06 月度开销 10 1449 07 和为给定数 10 1906 08 不重复地输出数 10 1790 09 膨胀的木棍 10 768 10 河中跳房子 10 2027 ------------------------------萌萌的分割线--

第11周练习

1.矩形分割 总时间限制: 1000ms 内存限制: 65536kB 描述: 平面上有一个大矩形,其左下角坐标(0,0),右上角坐标(R,R).大矩形内部包含一些小矩形,小矩形都平行于坐标轴且互不重叠.所有矩形的顶点都是整点.要求画一根平行于y轴的直线x=k(k是整数) ,使得这些小矩形落在直线左边的面积必须大于等于落在右边的面积,且两边面积之差最小.并且,要使得大矩形在直线左边的的面积尽可能大.注意:若直线穿过一个小矩形,将会把它切成两个部分,分属左右两侧. 输入: 第一行是整数R,表示大矩形

效率和开销问题是递归最大的缺点

递归在解决某些问题的时候使得我们思考的方式得以简化,代码也更加精炼,容易阅读.那么既然递归有这么多的优点,我们是不是什么问题都要用递归来解决呢?难道递归就没有缺点吗?今天我们就来讨论一下递归的不足之处.谈到递归就不得不面对它的效率问题. 为什么递归是低效的 还是拿斐波那契(Fibonacci)数列来做例子大发888娱乐城.在很多教科书或文章中涉及到递归或计算复杂性的地方都会将计算斐波那契数列的程序作为经典示例.如果现在让你以最快的速度用C#写出一个计算斐波那契数列第n个数的函数(不考虑参数小于1

http://stormzhang.com/opensource/2016/06/26/android-open-source-project-recommend1/

转载自:http://stormzhang.com/opensource/2016/06/26/android-open-source-project-recommend1/ 推荐他的所有博文~ 图片加载几乎是任何 Android 项目中必备的需求,而图片加载的开源库也越来越多,我们姑且在 GitHub 上搜索下 android image 关键字,出来的前五个按照 Star 数排序的项目如下: 可以看到前四个是大家比较熟知的图片加载库,有 UniversalImageLoader.Picass

06 Locking and Latching

本章提要---------------------------------------------------------------6,7,8,9,10,11 这 6 章要细看, 从本章开始how Oracle locks both data and shared data structures(比如在SGA中的)锁的机制 和 如何实现--------------------------------------------------------------- 1. 锁的概念和 oracle锁

MySQL8.0 · 优化器新特性 · Cost Model, 直方图及优化器开销优化

摘要: MySQL当前已经发布到MySQL8.0版本,在新的版本中,可以看到MySQL之前被人诟病的优化器部分做了很多的改动,由于笔者之前的工作环境是5.6,最近切换到最新的8.0版本,本文涵盖了一些本人感兴趣的和优化器相关的部分,主要包括MySQL5.7的cost model以及MySQL8.0的直方图功能. MySQL当前已经发布到MySQL8.0版本,在新的版本中,可以看到MySQL之前被人诟病的优化器部分做了很多的改动,由于笔者之前的工作环境是5.6,最近切换到最新的8.0版本,本文涵盖