题目大意:

N ( 1 ≤ N ≤ 100,000 )个 工作日 ,分M ( 1 ≤ M ≤ N ) 个 清算月

一个 清算月 包含一个工作日或更多连续的工作日,每一个工作日都仅被包含在一个 清算月 当中。

按顺序分组,得到一个最大值最小化的月度开支(即 在 所有可能的分组结果的最大值 中得到一个最小的)

Input

Line 1:   Two space-separated integers: N and M

Lines 2..N+1:   Line i+1 contains the number of dollars Farmer John spends on the i-th day

Output

Line 1:   The smallest possible monthly limit Farmer John can afford to live with.

Sample Input

7 5
100
400
300
100
500
101
400

Sample Output

500

Hint

If Farmer John schedules the months so that the first two days are a month, the third and fourth are a month, and the last three are their own months, he spends at most $500 in any month. Any other method of scheduling gives a larger minimum monthly limit.

 

思路来自:http://hzwer.com/2661.html

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int n,m,ans,a[];
  4. int judge(int mid)
  5. {
  6. int sum=,cnt=;
  7. for(int i=;i<=n;i++)
  8. {
  9. if(sum+a[i]<=mid) sum+=a[i];
  10. /// 连加 分为一组 直到该组总和大于mid
  11. else
  12. {
  13. sum=a[i]; cnt++; ///cnt记下组数 sum从a[i]开始重新连加
  14. if(cnt>m || sum>mid) return ;
  15. /// 若组数超过m 或 有比mid更大的花费 返回0
  16. }
  17. }
  18. return ;
  19. }
  20. int main()
  21. {
  22. scanf("%d%d",&n,&m);
  23. for(int i=;i<=n;i++) scanf("%d",&a[i]);
  24. int le=,rig=;
  25. while(le<=rig) ///不断缩小范围直到找到答案
  26. {
  27. int mid=(le+rig)>>;
  28. ///取中值 mid小了就le=mid+1向右找 否则就rig=mid-1向左找
  29. if(judge(mid)) /// 若返回1 mid>=答案
  30. {
  31. ans=mid; /// 先保存mid
  32. rig=mid-;
  33. ///若此时mid=答案 而rig=mid-1了 继续循环在judge()时只会进入else部分直到跳出循环。否则mid大了 继续缩小直到得到mid=答案。
  34. }
  35. else le=mid+; /// 若返回0 则花费中有比mid更大的 mid小了
  36. }
  37. printf("%d\n",ans);
  38.  
  39. return ;
  40. }

在一场比赛时用了这个方法,一直超时,其实可以在左右值上加个小优化

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int n,m,ans,a[];
  4. int judge(int mid)
  5. {
  6. int sum=,cnt=;
  7. for(int i=;i<=n;i++)
  8. {
  9. if(sum+a[i]<=mid) sum+=a[i];
  10. /// 连加 分为一组 直到该组总和大于mid
  11. else
  12. {
  13. sum=a[i]; cnt++; ///cnt记下组数 sum从a[i]开始重新连加
  14. if(cnt>m || sum>mid) return ;
  15. /// 若组数超过m 或 有比mid更大的花费 返回0
  16. }
  17. }
  18. return ;
  19. }
  20. int main()
  21. {
  22. scanf("%d%d",&n,&m);
  23. int le=,rig=;
  24. for(int i=;i<=n;i++){
  25. scanf("%d",&a[i]);
  26. le=min(le,a[i]);
  27. rig+=a[i];
  28. }
  29. while(le<=rig) ///不断缩小范围直到找到答案
  30. {
  31. int mid=(le+rig)>>;
  32. ///取中值 mid小了就le=mid+1向右找 否则就rig=mid-1向左找
  33. if(judge(mid)) /// 若返回1 mid>=答案
  34. {
  35. ans=mid; /// 先保存mid
  36. rig=mid-;
  37. ///若此时mid=答案 而rig=mid-1了 继续循环在judge()时只会进入else部分直到跳出循环。否则mid大了 继续缩小直到得到mid=答案。
  38. }
  39. else le=mid+; /// 若返回0 则花费中有比mid更大的 mid小了
  40. }
  41. printf("%d\n",ans);
  42.  
  43. return ;
  44. }

USACO2007 Monthly Expense /// 二分法 oj21658的更多相关文章

  1. BZOJ1639: [Usaco2007 Mar]Monthly Expense 月度开支

    1639: [Usaco2007 Mar]Monthly Expense 月度开支 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 529  Solved: ...

  2. BZOJ 1639: [Usaco2007 Mar]Monthly Expense 月度开支( 二分答案 )

    直接二分答案然后判断. ----------------------------------------------------------------------------- #include&l ...

  3. 1639: [Usaco2007 Mar]Monthly Expense 月度开支

    1639: [Usaco2007 Mar]Monthly Expense 月度开支 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 593  Solved: ...

  4. BZOJ【1639】: [Usaco2007 Mar]Monthly Expense 月度开支

    1639: [Usaco2007 Mar]Monthly Expense 月度开支 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 700  Solved: ...

  5. POJ-3273 Monthly Expense (最大值最小化问题)

    /* Monthly Expense Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10757 Accepted: 4390 D ...

  6. Divide and Conquer:Monthly Expense(POJ 3273)

    Monthly Expense 题目大意:不废话,最小化最大值 还是直接套模板,不过这次要注意,是最小化最大值,而不是最大化最小值,判断的时候要注意 联动3258 #include <iostr ...

  7. Monthly Expense(二分查找)

    Monthly Expense Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 17982 Accepted: 7190 Desc ...

  8. POJ 3273 Monthly Expense(二分查找+边界条件)

    POJ 3273 Monthly Expense 此题与POJ3258有点类似,一开始把判断条件写错了,wa了两次,二分查找可以有以下两种: ){ mid=(lb+ub)/; if(C(mid)< ...

  9. [ACM] POJ 3273 Monthly Expense (二分解决最小化最大值)

    Monthly Expense Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14158   Accepted: 5697 ...

随机推荐

  1. JAVA中 成员变量和和实例变量区别

    java语言支持的变量类型 类变量:独立于方法之外的变量,用 static 修饰. 局部变量:类的方法中的变量. 实例变量(全局变量):独立于方法之外的变量,不过没有 static 修饰. publi ...

  2. LitJson使用中的一些问题

    http://blog.csdn.net/n5/article/details/45030063

  3. 6.1_springboot2.x分布式-整合SpringCloud

    1.SpringCloud简介 ​ Spring Cloud是一个分布式的整体解决方案.Spring Cloud 为开发者提供了在分布式系统(配置管理,服务发现,熔断,路由,微代理,控制总线,一次性t ...

  4. C# 反射入门

    反射 别的用处先不管,至少在WinForm登录后的权限控制上有大用,比如登录后的窗体左侧树,点击通过字符串创建出窗体实例 案例如下图 AssTest类很简单 namespace assemblyTes ...

  5. Windows平台将远程服务器的目录挂载为本地磁盘

    我们在设置数据库自动备份时,为了数据的安全往往需要直接将数据备份到远程服务器上.在Linux可以通过NFS挂载来实现,在Windows平台可以直接通过net use+subst来实现将远程服务器的目录 ...

  6. 2019-4-29-.NET-Standard

    title author date CreateTime categories .NET Standard lindexi 2019-4-29 12:7:26 +0800 2018-2-13 17:2 ...

  7. 标准 IO 测试 可以打开多少流

    #include <stdio.h> #include <string.h> #include <errno.h> //trerror(errno) int mai ...

  8. docker Dockerfile学习---构建redis环境

    1.创建项目目录并下载包及文件 mkdir centos_redis cd centos_redis wget http://download.redis.io/releases/redis-5.0. ...

  9. Peasy.NET学习之并发问题处理

    Peasy.net之并发处理 BusinessServiceBase是ServiceBase的自定义实现,提供了额外的独特功能 首先,创建一个业务服务,该业务服务必须继承BusinessService ...

  10. linux redis的启动---后台启动

    1.启动redis服务: redis-server 如果想要开启后台进程: 1.找到redis.conf里边的 把no 改为yes. 2.redis-server redis.conf(这个是针对两个 ...