HDOJ1069 Monkey and Banana

题目大意:输入数字n表示箱子的种类数,下面有n行数据,每行数据有三个数据xi,yi,zi表示一种箱子的数据。每种箱子有无限个,xi,yi,zi中的任意两个数字都可以作为箱子的长、宽,剩下的一个数字表示箱子的高。从下往上堆积箱子,上面箱子的长、宽必须严格小于下面箱子的长、宽(不能相等),求堆积箱子的最大高度。

首先任意一行数据都可以等价为六种箱子。设(x,y,z)表示一种箱子的长、宽、高分别为x,y,z。则一行数据xi,yi,zi可以等效为六种箱子:(xi,yi,zi),(xi,zi,yi),(yi,xi,zi),(yi,zi,xi),(zi,xi,yi),(zi,yi,xi)每种箱子有无限个。其次,上面的箱子长宽必须严格小于下面的箱子,我们就将各种箱子按照长由大到小排序,长相等的情况下宽由大到小排序。则对于第i种箱子,上面只能摆放序号更大的箱子。

设f[i]表示最上层是第i种箱子的最大高度,max_height表示堆积箱子的最大高度,num表示箱子的种类数。则

max_height=max{ f[1],f[2],f[3].......f[num-1],f[num]}

现在我们的目标变为求f[i],这个时候我们遍历所有比i小的序号,看看哪种箱子可以放在第i种箱子下面,设第k1,k2种箱子可以放在第i种箱子的下面,第i种箱子的高度为h[i],则f[i]=max{ h[i]+f[k1] ,h[i]+f[k2] },即可求出max_height。

代码如下:

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

typedef struct{
    int x,y,z;//长、宽、高
} Block;
int n;
int f[200];//f[i]:最上面的一个block是第i种block,最大高度
Block block[200];

void sort_blocks(int num){
    //按照长排序,长由大到小,长相等的话,宽更大的排在前面
    Block tmp;
    for(int i=2;i<=num;i++){
        tmp=block[i];
        int j=0;
        for(j=i-1;j>0;j--){
            if(block[j].x<tmp.x) block[j+1]=block[j];
            else if(block[j].x==tmp.x){
                if(block[j].y<=tmp.y) block[j+1]=block[j];
                else break;
            }
            else break;
        }
        block[j+1]=tmp;
    }

}
int main(){
    int tmp[3];
    int num;//记录有几种block
    int max_height;
    int n2=0;
    while(cin>>n && n!=0){
        n2++;
        num=0;
        max_height=-1;
        for(int i=1;i<=n;i++){
            //每一组数据等价与6种block
            cin>>tmp[0]>>tmp[1]>>tmp[2];
            block[num+1].x=tmp[0];block[num+1].y=tmp[1];block[num+1].z=tmp[2];
            block[num+2].x=tmp[0];block[num+2].y=tmp[2];block[num+2].z=tmp[1];
            block[num+3].x=tmp[1];block[num+3].y=tmp[0];block[num+3].z=tmp[2];
            block[num+4].x=tmp[1];block[num+4].y=tmp[2];block[num+4].z=tmp[0];
            block[num+5].x=tmp[2];block[num+5].y=tmp[0];block[num+5].z=tmp[1];
            block[num+6].x=tmp[2];block[num+6].y=tmp[1];block[num+6].z=tmp[0];
            num+=6;
        }
        sort_blocks(num);

        for(int i=1;i<=num;i++){
            //计算f[i]:最上面的一个block是block[i]的情况下,最大高度
            int tmp2=0;
            tmp2=block[i].z;
            for(int j=i-1;j>0;j--){
                //判断block[j]能否在block[i]的下面
                if(block[j].x>block[i].x && block[j].y>block[i].y){
                    tmp2=max(tmp2,block[i].z+f[j]);
                }
            }//tmp2:最上面是block[i],最大高度
            f[i]=tmp2;
            max_height=max(max_height,tmp2);
        }
        cout<<"Case "<<n2<<": maximum height = "<<max_height<<endl;
    }

}

猜你喜欢

转载自blog.csdn.net/LOVETEDA/article/details/82942622