ZOJ_1093(Monkey and Banana)

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1093
记得暑假时看过这道题,但是昨天上ZOJ想找DP题,发现手册上的第一道DP水题——也就是这道1093居然没有AC掉,所以就
想着再做一下,结果真的对DP没感觉,居然没做出来,今天早上想了好久还是没有做对,最后看了下大牛的思路,终于A掉了。
这种算法不是很给力,但是容易些。这道题就是砌砖,要求上面的砖比下面的小(长和宽),给你n块砖,找出能砌的最大高
度。先贴下代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct aa
{
    int x,y,z;     //x,y,z分别代表长宽高
}S;
S d[100];
/*从大到小排序*/ 
int cmp(const void *_p,const void *_q)
{
    S *p = (S *)_p;
    S *q = (S *)_q;
    if( p->x == q->x) return p->y - q->y;
    return p->x - q->x;
 
}
int main()
{
    int N,i,j,a,b,c,a1,b1,c1,cnt = 1,max;
    while(scanf("%d",&N),N)
    {
        for(i = 1; i <= N*3; i += 3)
        {
            scanf("%d%d%d",&a,&b,&c);
            /* 找出最大值c1,最小值 a1*/
            a1 = a; if(a1 > b) a1 = b; if(a1 > c) a1 = c;
            c1 = a; if(c1 < b) c1 = b; if(c1 < c) c1 = c;
            b1 = a + b + c - a1 - c1;
            /*始终保证x
>=y,方便嵌套*/
            d[i].x = c1; d[i].y = b1; d[i].z = a1;
            d[i+1].x = b1; d[i+1].y = a1; d[i+1].z = c1;
            d[i+2].x = c1; d[i+2].y = a1; d[i+2].z = b1;
        }
        d[0].x = d[0].y = d[0].z = 0;
        qsort( d, N*3 + 1, sizeof(d[0]),cmp);
        /*排完序,可以堆砖了,从最下面开始累计高度*/
 
 
        for(i = 0; i <= N*3; i++)
        {
            max = 0;
            for(j = 0; j < i; j++)
            {
                if(d[i].x > d[j].x && d[i].y > d[j].y && d[j].z > max)
                    max = d[j].z; //找到能放上第i块砖的砖中的最大累计高度
            }
            d[i].z += max; // d[i].z更新成第i块砖的累计高度(包括其本身高度)
        }
        max = 0;
        for(i = 0; i <= N*3; i++)
        {
            if(d[i].z > max)
                max = d[i].z;
        }
        printf("Case %d: maximum height = %d\n",cnt,max);            
        cnt++;   
    }
    return 0;
}
一块砖有三种摆法,我们将一块砖的三种不同摆放情况下的长、宽、高存入数组d中,然后进行排序,以长度为第一参考量,
宽度为第二参考量,进行从大到小的排序,这样一来第i块砖只能放在前i-1块砖上。之后的工作就是找max了,max用累计
高度来求,将所有的累计高度求出来,进行比较找最大值。感觉做得像枚举了,时间复杂度有点高,好在数据不大!DP是条
很长的路。            
              
 
 
 
 
 

转载于:https://www.cnblogs.com/Yu2012/archive/2011/09/29/2195228.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值