---恢复内容开始---

Description

 

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 calledscribers. 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

这道题首先应该想好思路,这道题其实是一个找限值的过程,比如说一个排列,我划分很多的区间,要求每一个区间都不能大于某个值,设这个值为m,那么这个值最小应该是多少,以例1为例,最小应为900,以例2为例,最小应该为100,为什么?因为你有可能将排列中某一个值划为一个区间,如果你限值小于900,那么900就进不了任何区间,划分就会出问题了

同样我们还可以得出m最大值应该是排列相加的总和(把整个排列划为一个区间)。

既然找好了限值的范围,那么限值有什么用呢?可以使用限值作为划多少区间的依据,我可以从从限值的最小处枚举到最大处,直到限值正好可以使区间划分为k个(注意这里可能有个精度问题)。可是枚举的方法虽然可以找到需求的那个值,但是。。。

超时啊,

虽然数组的长度只有500,但是数组元素的最大值可达一千万,一千万乘以五百是什么概念?这样枚举时间复杂度为m*n,超时。。

最好的方法是二分查找进行优化,以限值去判断,如果说这个限值使得区间划分数大于k,那么限值肯定要再大一些,往右查,反之则往左查

这样的时间复杂度是mlogn,时间性能大大提高...

#include"iostream"
#include"algorithm"
#include"cstring"
#include"cstdio"
using namespace std;
int n,k;
int a[];
long long tot;
int maxa; void Init()
{
cin>>n>>k;
tot=;
maxa=-;
for(int i=; i<n; i++)
{
cin>>a[i];
tot+=a[i];
maxa=max(a[i],maxa);
}
//sort(a,a+n);
} int need(long long num)
{
long long c=;
int sum=;
for(int i=; i<n; i++) if(c+a[i]<=num) c+=a[i];
else
{
c=a[i];
sum++;
}
return sum;
} void print(long long num)
{
int last[];
long long done = ;
memset(last, , sizeof(last));
int remain = k;
for(int i = n-; i >= ; i--)
{
if(done + a[i] > num || i+ < remain)
{
last[i] = ;
remain--;
done = a[i];
}
else
{
done += a[i];
}
}
for(int i = ; i < n-; i++)
{
printf("%d ", a[i]);
if(last[i]) printf("/ ");
}
printf("%d\n", a[n-]);
} void guess()
{
long long l,r,m;
l=maxa;
r=tot;
while(l<r)
{
m=l+(r-l)/;
if(need(m)<=k) r=m;
else l=m+;
}
print(l);
} int main()
{
int T,t;
cin>>T;
t=T;
while(T--)
{
Init();
guess();
}
return ;
}

集训第四周(高效算法设计)B题 (二分查找优化题)的更多相关文章

  1. 集训第四周(高效算法设计)N题 (二分查找优化题)

    原题:poj3061 题意:给你一个数s,再给出一个数组,要求你从中选出m个连续的数,m越小越好,且这m个数之和不小于s 这是一个二分查找优化题,那么区间是什么呢?当然是从1到数组长度了.比如数组长度 ...

  2. 集训第四周(高效算法设计)C题 (二分查找优化题)

    Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...

  3. 数据结构和算法设计专题之---二分查找(Java版)

    1.前提:二分查找的前提是需要查找的数组必须是已排序的,我们这里的实现默认为升序 2.原理:将数组分为三部分,依次是中值(所谓的中值就是数组中间位置的那个值)前,中值,中值后:将要查找的值和数组的中值 ...

  4. 南理第八届校赛同步赛-F sequence//贪心算法&二分查找优化

    题目大意:求一个序列中不严格单调递增的子序列的最小数目(子序列之间没有交叉). 这题证明贪心法可行的时候,可以发现和求最长递减子序列的长度是同一个方法,只是思考的角度不同,具体证明并不是很清楚,这里就 ...

  5. js基本算法:冒泡排序,二分查找

    知识扩充: 时间复杂度:算法的时间复杂度是一个函数,描述了算法的运行时间.时间复杂度越低,效率越高. 自我理解:一个算法,运行了几次时间复杂度就为多少,如运行了n次,则时间复杂度为O(n). 1.冒泡 ...

  6. Java数据结构和算法总结-数组、二分查找

    前言:在平时开发中数组几乎是最基本也是最常用的数据类型,相比链表.二叉树等又简单很多,所以在学习数据和算法时用数组来作为一个起点再合适不过了.本篇博文的所有代码已上传 github ,对应工程的 ar ...

  7. 数据结构和算法:Python实现二分查找(Binary_search)

    在一个列表当中我们可以进行线性查找也可以进行二分查找,即通过不同的方法找到我们想要的数字,线性查找即按照数字从列表里一个一个从左向右查找,找到之后程序停下.而二分查找的效率往往会比线性查找更高. 一. ...

  8. C#LeetCode刷题-二分查找​​​​​​​

    二分查找篇 # 题名 刷题 通过率 难度 4 两个排序数组的中位数 C#LeetCode刷题之#4-两个排序数组的中位数(Median of Two Sorted Arrays)-该题未达最优解 30 ...

  9. Leedcode算法专题训练(二分查找)

    二分查找实现 非常详细的解释,简单但是细节很重要 https://www.cnblogs.com/kyoner/p/11080078.html 正常实现 Input : [1,2,3,4,5] key ...

随机推荐

  1. 安装使用electron辛路历程

    安装使用electron辛路历程 成功安装electron以及成功使用第一个应用,整整花费了我一整天的时间,各种百度,各种尝试.最终,终于总结了一个亲测可行的终极可执行方案: electron 简单介 ...

  2. visual studio中使用clrscr程序出错

    clrscr()函数的作用是“清屏”,即把标准输出设备中以前的显示记录清除,包含在头文件#include<conio.h>中,但暂时较旧的编译器中没有这个. 如果想要具有相同作用的函数,可 ...

  3. [SHOI2002]取石子游戏之三

    Wythoff's Game,详解请见浅谈算法--博弈论中的例6 /*program from Wolfycz*/ #include<cmath> #include<cstdio&g ...

  4. 2-SAT问题(白书)

    1. 定义 给定一个布尔方程,判断是否存在一组布尔变量的真值指派使整个方程为真的问题,被称为布尔方程的可满足性问题(SAT).SAT问题是NP完全的,但对于满足一定限制条件的SAT问题,还是能够有效求 ...

  5. XML To Linq 读取Sharepoint列表中的附件列信息

    通过页面查看,列表附件信息列的内容如下: var x = @"<div class='ExternalClass9936DCD1F074427B891D09CFCEFC2AB6'> ...

  6. php微信自动发红包

    <?phpheader('Content-type:text');define("TOKEN", "weixin");$wechatObj = new w ...

  7. JDK集合框架--ArrayList

    ArrayList,从类名就可以看出来,这是由数组实现的List,即内部是用数组保存元素的有序集合.先看看主要的成员变量,比较简单: public class ArrayList<E> e ...

  8. Java操作pdf: JarsperReport的简单使用

    在企业级应用开发中,报表生成.报表打印下载是其重要的一个环节.除了 Excel 报表之外,PDF 报表也有广泛的应用场景. 目前世面上比较流行的制作 PDF 报表的工具如下: iText PDF :i ...

  9. [BZOJ1061][Noi2008]志愿者招募 线性规划+费用流

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1061 根据题意列方程,然后用网络流解线性规划. 题解直接贴ByVoid的吧,太神了:htt ...

  10. 架构(Architecture)随想

    架构(Architecture)的意义: 先不要看什么是架构,先看下architect是什么,没有错,它是建筑师,在一块空地上build高楼大厦的人,它是一个designer,设计好整个大楼,也是一个 ...