您的位置:首页 > 其它

POJ 1017 Packets (典型的贪心算法)

2012-08-23 11:01 871 查看
地址:http://poj.org/problem?id=1017

翻译:http://poj.grids.cn/practice/1017/

思路:贪心算法 , 其实这道题的关键就是要解决2*2规格的。处理的时候要注意向上调整

题目分析:有6*6规格的箱子和一大堆木块 用多少箱子可以把木块都装下

先放大的6*6 5*5 4*4 都需要新开箱子 每4个3*3需要开个新箱子 算下剩多少2*2和1*1的 如果不够再开箱子

如果一个箱子中放置了一个6*6的产品,则此箱子中无法放置其它产品;
若放置一个5*5的产品,则此箱子中还可放置11个1*1的产品;
若放4*4的产品,还可放5个2*2的产品。
若放置3*3的产品,可以放置4个、3个、2个、1个,剩余的空位分别对应可以放置0个1*1,0个2*2; 5个1*1,1个2*2; 6个1*1,3个2*2; 7个1*1,5个2*2;
若放2*2产品,可放9个;
若放1*1产品,可放36个

代码如下:

#include <iostream>
using namespace std;
int main()
{
int b6,b5,b4,b3,b2,b1; //不同大小的木块个数
int nTotal = 0; //最少需要的箱子数目
int c1; //当前能放 1*1 木块的空格数目
int c2; //当前能放 2*2 木块的空格数目
int Contain2[4] = { 0, 5, 3, 1 }; //记录被3*3的占用之后,还剩多少给2*2的使用
while(1)
{
cin>>b1>>b2>>b3>>b4>>b5>>b6;//输入1*1到6*6箱子的个数
if (b1 == 0 && b2 == 0 && b3 == 0 && b4 == 0
&& b5 == 0 && b6 == 0) break;
nTotal = b6 + b5 + b4 + (b3 + 3)/4;   //只能装1个6*6的,1个5*5的,1个4*4的,而3*3的需要多情况考虑,3*3的需要向上调整,你懂的。。。。。
//这里有一个小技巧 (b3+3)/4 正好等于b3除以4向上取整的结果,下同
c2 = 5 * b4 + Contain2[b3 % 4];  //放2*2的数目等于放一个4*4时需要5个2*2加上放1到4个3*3时各需要的数目 ,即还可以装多少个2*2的
if(b2 > c2)    nTotal += (b2 - c2 + 8 ) / 9; //向上调整 ,总的2*2的个数减去装过的2*2的个数,得到剩余的2*2的个数,此个数加上8然后除以9就正好等于它除以9向上取整的结果,之所以总数要加上这个数是由于若单独装2*2,可以装9个
c1 = 36 * nTotal - 36 * b6 - 25 * b5 - 16 * b4 - 9 * b3 - 4 * b2;  //还可以装多少个1*1的,妙啊!
if(b1 > c1)    nTotal += ( b1 - c1 + 35 ) / 36; //向上调整 ,总的1*1的个数减去装过的1*1的个数,得到剩余的1*1的个数,此个数加上35然后除以36就正好等于它除以36向上取整的结果,之所以总数要加上这个数是由于若单独装1*1,可以装36个
cout << nTotal << endl;
}
return 0;
}


参考借鉴代码如下:

#include<iostream>
using namespace std;
int pk[7];
int pk3[4]={0,5,3,1}; //记录被3*3的占用之后,还剩多少给2*2的使用
int main()
{
int i;
bool flag;
for(i=1;i<=6;i++)
{
scanf("%d",&pk[i]);
if(pk[i])
flag=true;
}
while(flag)
{
int sum=0;
flag=false;
sum=pk[4]+pk[5]+pk[6]+(pk[3]+3)/4;//向上调整
int left2=pk[4]*5+pk3[pk[3]%4];   //还可以装多少个2*2的
if(left2<pk[2])
sum+=(pk[2]-left2+8)/9;//向上调整
int left1=sum*36-pk[2]*4-pk[3]*9-pk[4]*16-pk[5]*25-pk[6]*36; //还可以装多少个1*1的,妙啊!
if(left1<pk[1])
sum+=(pk[1]-left1+35)/36;//向上调整
printf("%d/n",sum);
for(i=1;i<=6;i++)
{
scanf("%d",&pk[i]);
if(pk[i])
flag=true;
}

}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: