北大ACM——Packets(贪心)

题意:有一堆等高的包装好的产品,有1×1,2×2,3×3,4×4,5×5,6×6六种包装,且有6×6的包裹,用来装这些包装好的产品。分别给出每种包装的数量,求所需的最少的包裹。

分析:一个包裹只能容下1个6×6余0空位,1个5×5余11,1个4×4余20,最多能容下4个3×3,9个2×2,36个1×1。
贪心策略:尽可能地利用空间。先从大的装起,6×6的独用一个,其它的若有剩余,则用1×1或2×2去填补空间,需要注意,5×5只能用1×1去填补剩余空间。

伪代码如下:
long long a1,a2,a3,a4,a5,a6;
long long lef2,lef3,lef4,lef5;
long long sum;
while(~scanf("%lld"a1-a6))
{
lef2=lef3=lef4=lef5=sum=0;
sum=a4+a5+a6;
lef5=a5×(36-25);lef4=a4×(36-16);
if(5×5有剩余){用1×1填补,a1减少且不得小于0}
if(4×4有剩余){先用2×2填补,a2减少且不得小于0,若仍有剩余,再用1×1填补,a1减少}
if(3×3没有剩余){sum+=a3/4}
else {sum+=a3/4+1;a3%4;lef3=36-9×a3;}
if(lef327){分别用2×2,1×1去填补}
else if(lef3
18) {…}
else if(lef3==9) {…}
if(a2!=0)
{if(a2没有剩余){sum+=a2/9;a2=0}
else{sum+=a2/9+1;a2%=9;lef2=36-4×a2;用1×1去填补}
}
if(a1!=0)
{
if(a1没有剩余){sum+=a1/36;a1=0;}
else {sum+=a1/36+1;a1=0;}
}
输出sum;
}

代码如下:

#include
using namespace std;
int main()
{
	long long a1,a2,a3,a4,a5,a6;
	long long lef2,lef3,lef4,lef5;
	long long sum;
	while(~scanf("%lld %lld %lld %lld %lld %lld",&a1,&a2,&a3,&a4,&a5,&a6)&&(a1||a2||a3||a4||a5||a6))
	{
		sum=lef2=lef3=lef4=lef5=0;
		sum=sum+a6+a5+a4;
		lef5=a5*(36-25);
		lef4=a4*(36-16);
	//	printf("%lld %lld\n",lef4,lef5);
		if(a3%4==0)
		    sum=sum+a3/4;
		else
		{
			sum=sum+a3/4+1;
			a3%=4;
			lef3=36-a3*9;
		}
		if(lef5!=0)
		{
			a1=a1-lef5;
			if(a1<0) a1=0;  //每次使用都要使数量减少,且不得小于0;
		}
		if(lef4!=0)
		{
			if(a2*4>=lef4)
			{
				a2=a2-lef4/4;//printf("%lld a2\n",a2);   注意代码顺序,WA了一次就因为顺序搞错
				lef4=0;
			}
			else
			{
				lef4=lef4-a2*4;
				 a2=0;
				a1=a1-lef4;
				if(a1<0) a1=0;
			}
		}
		if(lef3!=0)
		{
			if(lef3==27)
			{
				if(a2>=5)
				{
					a2=a2-5;
					lef3=7;
				}
				else
				{
					lef3=lef3-a2*4;
					a2=0;
				}
				a1=a1-lef3;
				if(a1<0) a1=0;
			}
			else if(lef3==18)
			{
				if(a2>=3)
				{
					a2=a2-3;
					lef3=6;
				}
				else
				{
					lef3=lef3-a2*4;
					a2=0;
				}
				a1=a1-lef3;
				if(a1<0) a1=0;
			}
			else if(lef3==9)
			{
				if(a2>=1)
				{
					lef3=5;
					a2--;
				}
				a1=a1-lef3;
				if(a1<0) a1=0;
			}
		}
		if(a2!=0)
		{
			if(a2%9==0)
			{
				sum=sum+a2/9;
				a2=0;
			}
			else
			{
				sum=sum+a2/9+1;
				a2%=9;
				lef2=36-4*a2;
				a1=a1-lef2;
				if(a1<0) a1=0;
			}
		}
		if(a1!=0)
		{
			if(a1%36==0)
			    sum=sum+a1/36;
			else
			    sum=sum+a1/36+1;
		}
		printf("%lld\n",sum);
	}
	return 0;
}

小结:分析仔细,从大的开始处理。不算难,但考验代码的能力。

你可能感兴趣的:(贪心)