【九度OJ】题目1502:最大值最小化

题目1502:最大值最小化

时间限制:1 秒

内存限制:128 兆

特殊判题:否

提交:591

解决:229

题目描述:

在印刷术发明之前,复制一本书是一个很困难的工作,工作量很大,而且需要大家的积极配合来抄写一本书,团队合作能力很重要。
当时都是通过招募抄写员来进行书本的录入和复制工作的, 假设现在要抄写m本书,编号为1,2,3...m, 每本书有1<=x<=100000页, 把这些书分配给k个抄写员,要求分配给某个抄写员的那些书的编号必须是连续的。每个抄写员的速度是相同的,你的任务就是找到一个最佳的分配方案,使得所有书被抄完所用的时间最少。

 

输入:

输入可能包含多个测试样例。
第一行仅包含正整数 n,表示测试案例的个数。
对于每个测试案例,每个案例由两行组成,在第一行中,有两个整数m和 k, 1<=k<=m<=500。 在第二行中,有m个整数用空格分隔。 所有这些值都为正且小于100000。

 

输出:

对应每个测试案例,
输出一行数字,代表最佳的分配方案全部抄写完毕所需要的时间。

 

样例输入:

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

样例输出:

1700
200

来源:

网易有道2013年校园招聘面试一面试题

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

解题思路:二分所有的可行解(元素最大值maxx~元素和sum),然后扫描原序列进行验证

复杂度分析:二分可行解——O(log(sum))

                    扫描原序列——O(M)

                    故求解复杂度为——O(M*log(sum) )

代码:

 

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;

int a[505];
int n, k, m;

bool judge(int x)
{
	int s = 0;  //记录当前所选序列的总和、
	int cnt = 0; //记录现在所选择的序列数,从而与 k进行比较 
	for(int i=0; i<m; i++)
	{
		if(x < a[i]) return false;
		if(s+a[i] <= x) 
		{
			s += a[i];
		}
		else{
			s = a[i];
			cnt++;
			if(cnt > k-1) return false;
		}	
	}
	return true;
}
int solve(int left, int right)
{
	int mid;
	while(left < right)
	{
		mid = left+(right-left)/2;
		if(judge(mid)) right = mid;
		else  left = mid+1;
	}
	return left;
}
int main()
{
	int maxx = 0, sum = 0;
	scanf("%d", &n);
	while(n--)
	{
		maxx = sum = 0;
		scanf("%d%d", &m, &k);
		for(int i=0; i<m ;i++)
		{
			scanf("%d", a+i);
			if(a[i] > maxx) maxx = a[i];
			sum += a[i];
		}
		printf("%d\n", solve(maxx, sum));
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值