HDU1069-Monkey and Banana(DP算法)

来源:互联网 发布:后端 知乎 编辑:程序博客网 时间:2024/06/08 14:04
题意:有n种长方体型的砖,每种有无数块,长宽高(x,y,z),砖可以任意翻转,
现把砖块一个一个叠起来,求能叠最高的高度,其中限定(放在上面的砖块的底面长宽都必须小于
放在下面的砖块)。
题解:DP算法


#include<stdio.h>
#include<string.h>
#define maxn 100+5
#define max 999999999               //表示地面的底面,无限大
int box[maxn][3];                   //保存每一块砖的底面和高度
int height[maxn];                   //保存每一块砖实现的高度
int num = 0;                        //砖块的编号


//构造砖块,a,b是底面,c是高。这里同一底面的砖块可以翻转一次,即ab对换
void oriente(int serial,int a,int b,int c)    
{
    box[serial][0] = a;
    box[serial][1] = b;
    box[serial][2] = c;
}


//搜索每一块砖能实现的最大高度
int DP(int serial)
{
    //如果第serial块砖已经计算过,直接返回结果(记忆式搜索),可减少耗时
    if(height[serial]!=-1)
        return height[serial];
    //所有砖块已经计算完毕
    if(serial>num)
        return 0;
    int t = 0;
    for(int i=1;i<=num;i++)
    {
        //第serial块砖能够放上去,直放/横放各一次,即底面a,b对换一下
        if((box[i][0]<box[serial][0]&&box[i][1]<box[serial][1])||
            (box[i][1]<box[serial][0]&&box[i][0]<box[serial][1]))
             t = DP(i)+box[i][2];
         //找到最优解
         if(t>height[serial])
            height[serial] = t;
    }
    return height[serial];
}


int main()
{
    int n,k=0;
    while(~scanf("%d",&n)&&n)
    {
        //这里记得每输入一组数据变初始化num,否则后面的数据会受前面的影响
        num = 0;
        //地面的长宽无限大
        box[0][0] = max;
        box[0][1] = max; 
        memset(height,-1,sizeof(height));
        k++;
        int a,b,c;
        //把每一块砖保存到box中,每一种砖经翻转有3个高度
        for(int i=0;i<n;i++)
        {
            scanf("%d%d%d",&a,&b,&c);
            oriente(++num,a,b,c);
            oriente(++num,b,c,a);
            oriente(++num,a,c,b);
        }
        //height[0]就是地板上能叠的最高高度
        printf("Case %d: maximum height = %d\n",k,DP(0));
    }
    return 0;
}
0 0
原创粉丝点击