[JSOI2007] 奶酪 题解 贪心 O(1)

本文解析了一道经典的算法题目——奶酪装盒问题。该问题要求计算不同形状的奶酪如何组合才能最大限度地装满盒子。文章详细阐述了解题思路,采用贪心算法进行求解,并提供了参考代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PID227 / [JSOI2007]奶酪
我的状态
查看最后一次评测记录
     
题目描述

奶酪和pizza一样,是一小块扇形的固体。在奶酪从工厂里生产出来的时候,一共有4种形状,编号为1~4,分别是圆心角为72º;,144º;,216º;,288º;的扇形。奶酪的盒子是圆形的,半径和奶酪的半径一致。也就是说,一块1号奶酪和一块4号奶酪可以恰好装入一个盒子,一块2号奶酪和一块3号奶酪可以恰好装入一个盒子。

你的任务是写一个程序,计算给定的奶酪最多可以装满几个盒子。

输入格式

一行,四个数字,表示1~4号奶酪的数量,都在0~100之内

输出格式

一个数字,表示可以装满几个盒子

样例输入
样例输出


原题地址:http://www.rqnoj.cn/problem/227




题解:


我们先将题目稍变一下:有a,b,c,d个体积为1,2,3,4的物体,问能装满多少个体积为5的箱子
然后我们不难列出所有能凑的式子:
5*1   3*1+1*2  1*1+2*2  2*1+1*3  1*2+1*3  1*1+1*4 (乘号前为数量,乘号后为体积)


我们发现1个箱子中最多只能装下1个4,那我们不妨先将4装入d个箱子中
我们又发现1个箱子中最多只能装下1个3,,并且不能和4放在一块,那不妨再将3放入c个箱子中
现在4和3的价值已经被榨干了,不管它们了(贪心)


然后我们考虑已经装了4的箱子是否要装个1将之填满呢?
答案是肯定的,因为“对于1而言”已经没有更划算的买卖了(贪心):只要消耗1个1,而且不用消耗2,就能得到1个满箱子


我们再考虑已经装了1个3的箱子,有2个问题?是装它还是装空箱子?如果装的话,装2个1还是装1个2?
装空箱子猜猜就是不划算的,而且无论使用“5*1  3*1+1*2  1*1+2*2”中的哪一个式子,都有办法用它们中的一部分凑到3体积,
也就是说,用1、2来装满5体积的话,相当于先装了3体积,再装剩下的2体积。那我还不如直接用已经装了3体积的那些箱子,少耗资源多好啊(贪心)。
那下一个问题,装2个1还是装1个2?
当然是装1个2了,因为1个2能做的事,2个1都能做,反之则不一定,因为我可以把2个1拆开用。既然如此,让没用的2上吧(贪心)。
小结一下,以上也就是先将1、4尽可能组合,2、3尽可能组合。
如果2没有了,而那些已经装了3的盒子还有并且还有1,就用2个1来装。


现在那些装了1个4或1个3的箱子已经处理完了,我们来处理手头剩下的1和2(如果有的话)。
还是老样子,2没有用,让它先上,先用2个2,1个1装,2不够了就用1个2,3个1装,还不够就用5个1装。
现在1、2、3、4都被榨干了,剩下的也都凑不了5了~

注意: a-=b/2; b%=2;  顺序不能换呀...





代码仅供参考:


#include<iostream>
using namespace std;

int main()
{
	int a,b,c,d;
	cin>>a>>b>>c>>d;
	int sum=0;
	if (a>=d)
	{
		sum+=d;
		a-=d;
		d-=d;
	}
	else {
		sum+=a;
		d-=a;
		a-=a;
	}
	
	if (b>=c)
	{
		sum+=c;
		b-=c;
		c-=c;
		
		if (a>=b/2)
		{
			sum+=b/2;
			a-=b/2;
			b%=2;
			
			if (b==1&&a>=3)
			{
				sum+=1;
				b-=1;
				a-=3;
			}
			
			sum+=a/5;
			a%=5;
				
		}
		else{
			sum+=a;
			b-=2*a;
			a-=a;
		}
	}
	else{
		sum+=b;
		c-=b;
		b-=b;
		
		if (a>=2*c)
		{
			sum+=c;
			a-=2*c;
			c-=c;
		}
		else
		{
			sum+=a/2;
			c-=a/2;
			a%=2;
		}
		
		sum+=a/5;
		a%=5;
	}
	cout<<sum<<endl;
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值