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是条
很长的路。