CordForce 604B More Cowbell(贪心 二分)

这篇博客介绍了如何运用贪心算法和二分搜索策略解决物品打包问题,具体是帮助Kevin将他的牛铃收藏品装进固定大小的盒子里,确保不超过每个盒子的容量限制,并尽可能减少使用的盒子数量。博主提供了两种解决方案:贪心策略是当箱子数量大于物品数量时,直接使用最大物品的尺寸作为盒子大小;二分搜索策略则在一定范围内查找最小的盒子尺寸,通过模拟分箱过程确定合适尺寸。这两种方法都在46毫秒内完成了计算。
摘要由CSDN通过智能技术生成

description

Kevin Sun wants to move his precious collection of n cowbells from Naperthrill to Exeter, where there is actually grass instead of corn. Before moving, he must pack his cowbells into k boxes of a fixed size. In order to keep his collection safe during transportation, he won’t place more than two cowbells into a single box. Since Kevin wishes to minimize expenses, he is curious about the smallest size box he can use to pack his entire collection.

Kevin is a meticulous cowbell collector and knows that the size of his i-th (1 ≤ i ≤ n) cowbell is an integer si. In fact, he keeps his cowbells sorted by size, so si - 1 ≤ si for any i > 1. Also an expert packer, Kevin can fit one or two cowbells into a box of size s if and only if the sum of their sizes does not exceed s. Given this information, help Kevin determine the smallest s for which it is possible to put all of his cowbells into k boxes of size s.

Input

The first line of the input contains two space-separated integers n and k (1 ≤ n ≤ 2·k ≤ 100 000), denoting the number of cowbells and the number of boxes, respectively.

The next line contains n space-separated integers s1, s2, …, sn (1 ≤ s1 ≤ s2 ≤ … ≤ sn ≤ 1 000 000), the sizes of Kevin’s cowbells. It is guaranteed that the sizes si are given in non-decreasing order.

Output

Print a single integer, the smallest s for which it is possible for Kevin to put all of his cowbells into k boxes of size s.

Examples

inputCopy
2 1
2 5
outputCopy
7
inputCopy
4 3
2 3 5 9
outputCopy
9
inputCopy
3 2
3 5 7
outputCopy
8

Note

In the first sample, Kevin must pack his two cowbells into the same box.

In the second sample, Kevin can pack together the following sets of cowbells: {2, 3}, {5} and {9}.

In the third sample, the optimal solution is {3, 5} and {7}.

贪心

如果箱子比物品多,那么就可以一个箱子放一个物品,箱子的最小容量就是最大的物品体积
如果箱子比物品少,分为箱子等于物品的一半和不等于。对于前者,每个箱子都是放两个物品。而后者,箱子中有放一个的有放两个的。如果要使箱子容量最小,就要把较大的单独放在一个箱子,剩下的两两放。如果最大的和别的一起放,体积显然大于单独放。除去单独放的几个,两两放的中剩下的第一大的和第一小的放一起,第二大的和第二小的放一起。最小值就是第n个和两两放的各组中的最大值

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;

int a[100005];

int main()
{
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	int ans=a[n];					
	if(k<n)
	{
		int m=2*k-n;						//单独放的盒子数量   m=k-(n-k) 
		n-=m;								//单独放的放完后,剩余的数量 
		for(int i=1;i<=n;)
			ans=max(ans,a[i++]+a[n--]);
	}
	cout<<ans;
	return 0;
}

还可以用二分做,提交均为46ms

二分

最后的答案要大于等于最大的物品,小于等于最大的物品的两倍。如果箱子数大于物品数,答案就为最大的物品,如果箱子数等于物品数的一半且有大于箱子数的物品体积相等且最大,答案则为最大物品的两倍。在这个区间二分查找答案。查找过程模拟分箱子即可

#include<iostream>
using namespace std;

int a[100005];

int main()
{
	int n,k;
	cin>>n>>k;
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	int i;
	int left=a[n],right=2*a[n],mid;
	int ans;
	while(left<=right)
	{
		mid=left+(right-left)/2;
		int l=1;
		int r=n;
		int m=0;
		while(l<r)
		{
			if(mid>=a[r]+a[l])
			{
				l++;
				r--;
				m++;
			}
			else
			{
				r--;
				m++;
			}
			if(m>k)
				break;
		};
		if(l==r)
			m++;
		if(m<=k)
		{
			ans=mid;
			right=mid-1;
		}
		else
			left=mid+1;
	}
	cout<<ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值