补充一下我对 POJ 3273 的理解,这肯定是我一生写的最多的题解。。。
题目:http://poj.org/problem?id=3273
当分成的组数越多,所有组的最大值就会越小或不变,这一点不难证明:
如果当前分成了group组,最大值是max,那么max的这一组天数>=1,这时把max的这一组再分成2组,总的组数变成了group+1,最大值显然会减小或不变(当还有另一组是max或者max组只包含一天时不变)。
所以组数和本题的答案是单调的关系。
设答案在区间[low, high],不难看出low是花费最多的一天的值,high是每天花费的总和。这样二分寻找答案,效率肯定是很高的。本题确实比较难理解,看了一个小时才差不多理解了,更多二分的细节在代码注释中。
#include <stdio.h>
#include <string.h> int n, m; //把n天分成m组
int money[]; //每天的钱数 //假设答案是mid,验证是否正确
//为了便于说明,设正确答案为ans
bool judge(int mid)
{
//sum表示一组的花费,cnt表示分的组数
int sum = , cnt = ;
for(int i = ; i < n; i++)
{
//因为假设答案是mid,所以当sum + money[i] <= mid时,第i天可以分到上一组中。
//这一点很显然,剩下的天数少了,ans当然会更优
if(sum + money[i] <= mid)
sum += money[i]; //如果第i天不能分到上一组,那么只能再分下一组了,这时组数+1
else
{
sum = money[i];
cnt++;
}
}
//如果分的组数>m,显然这时假设的答案mid太小了,所以mid要增大
if(cnt > m)
return ; //否则cnt<=m。
//如果cnt<m,根据上面说的单调关系,分更多的组ans会更优,即mid<ans
//如果cnt==m,说明此时可以在分m组的情况下ans<=mid,这时继续尝试在[low,mid]寻找ans
else
return ;
} int main()
{
int low = , high = ;
scanf("%d %d", &n, &m);
for(int i = ; i < n; i++)
{
//输入每天的花费,计算low和high
scanf("%d", &money[i]);
if(low < money[i])
low = money[i];
high += money[i];
} //二分寻找答案,循环在low==high时结束,这时low和high的值都是答案,输出其中一个就可以
while(low < high)
{
//设答案是mid
int mid = (high + low) / ;
if(judge(mid))
high = mid;/*这里有一点不理解,为什么网上大多数代码写的high=mid-1也是正确的,
如果是在judge中提到的cnt==m的情况,那么ans是<=mid的啊,为什么ans所
在的区间可以跳过mid这个点呢?请知道的回复我,谢谢。*/
else
low = mid + ;
}
//输出high也可以
printf("%d\n", low);
return ;
}
补充一下我对 POJ 3273 的理解,这肯定是我一生写的最多的题解。。。的更多相关文章
- POJ 3273 Monthly Expense(二分查找+边界条件)
POJ 3273 Monthly Expense 此题与POJ3258有点类似,一开始把判断条件写错了,wa了两次,二分查找可以有以下两种: ){ mid=(lb+ub)/; if(C(mid)< ...
- poj 1696 叉积理解
Space Ant Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 3967 Accepted: 2489 Descrip ...
- 二分搜索 POJ 3273 Monthly Expense
题目传送门 /* 题意:分成m个集合,使最大的集合值(求和)最小 二分搜索:二分集合大小,判断能否有m个集合. */ #include <cstdio> #include <algo ...
- 【POJ 3273】 Monthly Expense (二分)
[POJ 3273] Monthly Expense (二分) 一个农民有块地 他列了个计划表 每天要花多少钱管理 但他想用m个月来管理 就想把这个计划表切割成m个月来完毕 想知道每一个月最少花费多少 ...
- POJ 3273 Monthly Expense二分查找[最小化最大值问题]
POJ 3273 Monthly Expense二分查找(最大值最小化问题) 题目:Monthly Expense Description Farmer John is an astounding a ...
- POJ 3273 Monthly Expense 二分枚举
题目:http://poj.org/problem?id=3273 二分枚举,据说是经典题,看了题解才做的,暂时还没有完全理解.. #include <stdio.h> #include ...
- poj 3273 Monthly Expense(贪心+二分)
题目:http://poj.org/problem?id=3273 题意:把n个数分成m份,使每份的和尽量小,输出最大的那一个的和. 思路:二分枚举最大的和,时间复杂度为O(nlog(sum-max) ...
- poj 3273 Monthly Expense (二分搜索,最小化最大值)
题目:http://poj.org/problem?id=3273 思路:通过定义一个函数bool can(int mid):=划分后最大段和小于等于mid(即划分后所有段和都小于等于mid) 这样我 ...
- POJ 3273 Monthly Expense(二分搜索)
Description Farmer John is an astounding accounting wizard and has realized he might run out of mone ...
随机推荐
- android颜色对应的xml配置值,颜色表
网上找的一些颜色值 XML配置 <?xml version="1.0" encoding="utf-8" ?> <resources> ...
- [GIF] Shape Objects in GIF Loop Coder
This lesson is a quick tour of the predefined shape objects in GIF Loop Coder. function onGLC(glc) { ...
- Lua开发环境搭建(Mac)
1.下载最新版的Lua,点击下载 2.下载完成后,解压压缩包,打开终端,cd进入Lua解压目录下 3. 在终端输入“make macosx”,编译lua 4.编译完成后,在终端输入”make test ...
- IIS8无法调用Oracle.DataAccess .dll问题
之前在.net平台下操作Oracle都是用的oracle.dataaccell.dll引用,但是服务器升级为II8后,发布的新服务有关Oracle数据库部分都无法运行,调试了好久发现是IIS8不支持低 ...
- 详解ExplosionField的使用,实现View的粉碎效果
小米平板卸载软件的时候,会有一个粉碎的效果,看起来很拉风,GitHub上有一个开源控件可以实现这个效果,我们一起来看看.先来看看效果图: 看起来不错吧,那我们今天就来详细说说ExplosionFiel ...
- cobbler部署
1.cobbler介绍 Cobbler是一个快速网络安装linux的服务,而且在经过调整也可以支持网络安装windows.该工具使用python开发,小巧轻便(才15k行python代码),使用简单的 ...
- <input> 标签
HTML5 中的新属性. 属性 值 描述 accept mime_type 规定通过文件上传来提交的文件的类型. align left right top middle bottom 不赞成使用. ...
- 读《编写高质量代码:改善JavaScript程序的188个建议》2
- javascript创建对象和属性的几种方式
一句话,javascript里面的对象,即是函数.方法. (一)第一种: a.声明对象:var JHSoft = JHSoft || {}; 或者 var JHSoft=new Object(); b ...
- cognos 10.2.2 导入samples数据源报错解决
操作系统:windows 2008R2 X64 数据库:oracle 10.2.0.1 X32 sid:cognosdb86 安装完samples后,执行IBM安装目录webcontent\sampl ...