抄书  (二分查找+贪心)

提示:二分查找一般写成非递归形式

时间复杂度:O(logn)

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85904#problem/B

Description

 

Copying Books

Before the invention of book-printing, it was very hard to make a copy of a book. All the contents had to be re-written by hand by so called scribers. The scriber had been given a book and after several months he finished its copy. One of the most famous scribers lived in the 15th century and his name was Xaverius Endricus Remius Ontius Xendrianus (Xerox). Anyway, the work was very annoying and boring. And the only way to speed it up was to hire more scribers.

Once upon a time, there was a theater ensemble that wanted to play famous Antique Tragedies. The scripts of these plays were divided into many books and actors needed more copies of them, of course. So they hired many scribers to make copies of these books. Imagine you have m books (numbered ) that may have different number of pages (     ) and you want to make one copy of each of them. Your task is to divide these books among k scribes, . Each book can be assigned to a single scriber only, and every scriber must get a continuous sequence of books. That means, there exists an increasing succession of numbers such that i-th scriber gets a sequence of books with numbers between bi-1+1 and bi. The time needed to make a copy of all the books is determined by the scriber who was assigned the most work. Therefore, our goal is to minimize the maximum number of pages assigned to a single scriber. Your task is to find the optimal assignment.

Input

The input consists of N cases. The first line of the input contains only positive integer N. Then follow the cases. Each case consists of exactly two lines. At the first line, there are two integers m and k,     . At the second line, there are integers separated by spaces. All these values are positive and less than 10000000.

Output

For each case, print exactly one line. The line must contain the input succession divided into exactly k parts such that the maximum sum of a single part should be as small as possible. Use the slash character (`/') to separate the parts. There must be exactly one space character between any two successive numbers and between the number and the slash.

If there is more than one solution, print the one that minimizes the work assigned to the first scriber, then to the second scriber etc. But each scriber must be assigned at least one book.

Sample Input

2
9 3
100 200 300 400 500 600 700 800 900
5 4
100 100 100 100 100

Sample Output

100 200 300 400 500 / 600 700 / 800 900
100 / 100 / 100 / 100 100 题意:
输入多组案例T,给你N本书,一个有M个人抄写,使M个人所抄写书所用的时间最少,输出分配方案。(1<=N<=100000,1<=M<=N,每个数在1到10000之间)
如果有多种可能的话,尽量在前面进行划分。 分析:
1.经典的最大值最小化问题,采用 贪心+二分查找
2.输出的时候用到贪心的思想,既尽量往前进行划分
3.利用二分查找找出满足题意的最大值,再利用贪心从后往前的方式划分成段,如果剩余可划分段与i+1的值相等(尽量靠前),则将剩余的段往前划分 代码:
 #include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = ; int n, m;
int p[MAXN], use[MAXN]; //标记数组use表示是否划分
long long low_bound, high_bound; //由于high_bound可能很多,用long long 来存储 void init()
{
low_bound=-;
high_bound=;
memset(use,,sizeof(use));
} int solve(int mid) //判断最大值所在区间是左还是右
{
int sum=,group=;
for(int i=n-;i>=;i--)
{
if(sum+p[i]>mid)
{
sum=p[i];
group++;
if(group>m) //看可以分成几组,若group>m,舍弃
return ;
}
else sum+=p[i];
}
return ;
} void print(int high_bound)
{
int group=,sum=;
for(int i=n-;i>=;i--)
{
if(sum+p[i]>high_bound) //从右边开始确定划分
{
use[i]=;
sum=p[i];
group++;
}
else sum+=p[i];
if(m-group==i+)
{
for(int j=;j<=i;j++)
use[j]=;
break;
}
}
for(int i=;i<n-;i++)
{
printf("%d ",p[i]);
if(use[i]) //确定‘/’的位置
printf("/ ");
}
printf("%d\n",p[n-]);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
{
scanf("%d",&p[i]);
if(low_bound<p[i])
low_bound=p[i];
high_bound+=p[i];
}
long long x=low_bound,y=high_bound;
while(x<=y) //二分,判断最小的最大值的区间
{
long long mid=x+(y-x)/;
if(solve(mid))
y=mid-;
else x=mid+;
}
print(x);
}
return ;
}
之前上选修课的时候听过贪心算法,但之前没有做过类似的题,感觉做的不是很好。
 

抄书(B - 二分查找)的更多相关文章

  1. jvascript 顺序查找和二分查找法

    第一种:顺序查找法 中心思想:和数组中的值逐个比对! /* * 参数说明: * array:传入数组 * findVal:传入需要查找的数 */ function Orderseach(array,f ...

  2. Java实现的二分查找算法

    二分查找又称折半查找,它是一种效率较高的查找方法. 折半查找的算法思想是将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小 于该中点 ...

  3. 从一个NOI题目再学习二分查找。

    二分法的基本思路是对一个有序序列(递增递减都可以)查找时,测试一个中间下标处的值,若值比期待值小,则在更大的一侧进行查找(反之亦然),查找时再次二分.这比顺序访问要少很多访问量,效率很高. 设:low ...

  4. java实现二分查找

    /** * 二分查找 * @param a * @param n * @param value * @return * @date 2016-10-8 * @author shaobn */ publ ...

  5. 最新IP地址数据库 二分逼近&二分查找 高效解析800万大数据之区域分布

    最新IP地址数据库  来自 qqzeng.com 利用二分逼近法(bisection method) ,每秒300多万, 比较高效! 原来的顺序查找算法 效率比较低 readonly string i ...

  6. c#-二分查找-算法

    折半搜索,也称二分查找算法.二分搜索,是一种在有序数组中查找某一特定元素的搜索算法. A 搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束: B 如果某一特定元素大于或者小 ...

  7. 【Python】二分查找算法

    二分查找:在一段数字内,找到中间值,判断要找的值和中间值大小的比较.如果中间值大一些,则在中间值的左侧区域继续按照上述方式查找.如果中间值小一些,则在中间值的右侧区域继续按照上述方式查找.直到找到我们 ...

  8. PHP实现文本快速查找 - 二分查找

    PHP实现文本快速查找 - 二分查找法 起因 先说说事情的起因,最近在分析数据时经常遇到一种场景,代码需要频繁的读某一张数据库的表,比如根据地区ID获取地区名称.根据网站分类ID获取分类名称.根据关键 ...

  9. java二分查找举例讨论

    最近做笔试题有这么一个关于二分查找的例子. 给一个有序数组,和一个查找目标,用二分查找找出目标所在index,如果不存在,则返回-1-(其应该出现的位置),比如在0,6,9,15,18中找15,返回3 ...

随机推荐

  1. Canvas 雾玻璃

    Demo http://lumixraku.github.io/demos/Fog/Fog.html Canvas tutorial 给大家安利一个学习Canvas的站点 http://www.htm ...

  2. ES6新特性简介

    ES6新特性简介 环境安装 npm install -g babel npm install -g babel-node //提供基于node的REPL环境 //创建 .babelrc 文件 {&qu ...

  3. 转: Nodejs 发送HTTP POST请求实例

    项目里面需要用到使用NodeJs来转发HTTP POST请求,把过程记录一下: exports.sendEmail = function (req, res) { res.send(200, req. ...

  4. VS2010 win32项目windows窗体程序 向导生成代码解析

    目录: 1.Win32项目的windows窗体程序的向导生成了如下代码 2.手工生成代码如下 3.当消息队列中没有消息需要处理,我们可以利用这段时间处理我们自己的任务 1.Win32项目的window ...

  5. PASCAL的读入优化

    没readkey的情况 type Tstring=record s:array[0..maxn] of char; n:longint; end; procedure scan(var S:Tstri ...

  6. 删除input或textarea输入框在移动版显示的阴影(Safari/iPhone)

    移动端浏览网页元素时,自动给input和textarea添加了内部阴影的效果,只需加入样式即可去除 input,textarea{-webkit-appearance: none;} input[ty ...

  7. 第七届河南省赛G.Code the Tree(拓扑排序+模拟)

    G.Code the Tree Time Limit: 2 Sec  Memory Limit: 128 MB Submit: 35  Solved: 18 [Submit][Status][Web ...

  8. [ javascript ] 司徒正美的fadeOut-fadeIn效果!

    首先感谢司徒正美的文章! 在司徒大神的博客看到一个简单的渐入渐出的效果.全然採用js实现. 例如以下: <!doctype html> <html dir="ltr&quo ...

  9. windows下搭建apache+php+mysql

    在windows下,apache和mysql都有自动化安装的程序,本篇则侧重从apache和php版本选择,php线程安全,apache和mysql安装启动服务,工作环境配置这几个方面来阐述windo ...

  10. Android视频应用去广告学习实践

    注意:本文仅仅供学习研究用途 第一步 素材搜集 腾讯视频应用:http://download.csdn.net/detail/itleaks/7991795      反汇编工具:           ...