蓝桥杯(算法提高)打包

问题描述

Lazy有N个礼物需要打成M个包裹,邮寄给M个人,这些礼物虽然很便宜,但是很重。Lazy希望每个人得到的礼物的编号都是连续的。为了避免支付高昂的超重费,他还希望让包裹的最大重量最小。

输入格式

一行两个整数N和M。
一行N个整数,表示N个礼物的重量。

输出格式

一个整数,表示最小的最大重量。

样例输入

3 2 1 1 2

样例输出

2

数据规模和约定

N, M <= 100,000   
重量 <= 1,000

在这里插入图片描述

结合csdn上Java和Python的题解,写出C++的题解
代码如下

#include<iostream>
using namespace std;
int weight[100010];
int b[100010];
int num,package;
bool judge(int mid){
	int curPack=1;//打包的数量
	int sum=0; //前几个包打包的重量 
	for(int i=0;i<num;i++){
		sum+=weight[i];//前几个包打包的重量 
		if(curPack>package){//已打包数量比送出的多 ,不合理 
			return false;
		}
		if(sum>mid){//打包的重量大于当前最大重量 
			sum=0;//对包的重量归零,对下一个的重量进行计算 
			curPack+=1;//放到下一个包打包 
			i-=1;//对最后一个来打包的包不打包 
		}
		else if(sum==mid){//相等就不用把最后一个来打包的包拿出来了 
			sum=0;
			curPack+=1;
		}
	}
	return true;
}
int main() {
	
	cin>>num>>package;
	int right=0;
	for(int i=0;i<num;i++){
		cin>>weight[i];//输入未打包的各个包的重量 
		right+=weight[i];//二分最右端是总重量 
	} 
	int mid=0;//中间值 
	int left=0;//最左值 
	while(left<right){
		mid=(left+right)/2;
		if(judge(mid)){//判断是否能够打包 
			right=mid;//在左半边找 
		}
		else{
			left=mid+1;//在右半边找 
		}
	}
	cout<<left;//左边的值是最小的最大打包重量 
    return 0;
}

使用二分法查找符合条件的值,在判断条件里枚举。
最小的最大包的重量存在于包的最大重量和包的总重量中,因此使用二分法。
使用枚举,进行打包,再看最终打包的数量是否大于分给朋友的数量,如果大于那么这个值不合适,寻找下一个最小的最大包重量进行判断。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值