这道题我陷入的几个坑是:
1.读题不仔细。上面的箱子的长和宽必须均小于下面的箱子的长和宽。我以为只要其中一个小于就行了。
2.虽然每个箱子可以用无数次,但是最多只能用三次。即取其中两边作为长和宽,第三条边作为高。
作为长和宽的两边必然是长大于等于宽。我一开始竟然是随机的选作长和宽!我在想什么!
3.关于qsort()函数
上午刚刚总结完这个函数,下午就发现错了并且被自己坑了。悲哀。
下面是正确的解释。
int cmp(const void *a, const void *b)
返回正数就是说 cmp 传入参数第一个要放在第二个后面, 负数就是传入参数第一个要放第二个前面, 如果是 0, 那就无所谓谁前谁后。
虽然是一次AC,但是一下午过去了。GG。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int max(int a, int b)
{
return a > b ? a : b;
}
int min(int a, int b)
{
return a < b ? a : b;
}
struct box {
int x, y, z;
}boxes[91];
// 降序
// 这里要好好想一下
int cmp(const void *a, const void *b)
{
box *ai = (box*)a;
box *bi = (box*)b;
if (ai->x == bi->x)
return bi->y - ai->y;
return bi->x - ai->x;
}
int h[91];
int main()
{
int c = 0;
int n;
int maxn;
int i, j;
int p, q, r;
while (scanf("%d", &n) && n)
{
c++;
for (i = 0; i < n; i++)
{
// 错在了这里
scanf("%d %d %d", &p, &q, &r);
boxes[i * 3 + 1].x = max(p, q); boxes[i * 3 + 1].y = min(p, q); boxes[i * 3 + 1].z = r;
boxes[i * 3 + 2].x = max(p, r); boxes[i * 3 + 2].y = min(p, r); boxes[i * 3 + 2].z = q;
boxes[i * 3 + 3].x = max(q, r); boxes[i * 3 + 3].y = min(q, r); boxes[i * 3 + 3].z = p;
}
n *= 3;
qsort(boxes + 1, n, sizeof(boxes[0]), cmp);
memset(h, 0, sizeof(h));
maxn = 0;
for (i = 1; i <= n; i++)
{
h[i] = boxes[i].z;
for (j = 1; j < i; j++)
{
if (boxes[i].x < boxes[j].x && boxes[i].y < boxes[j].y)
h[i] = h[i] > (h[j] + boxes[i].z) ? h[i] : (h[j] + boxes[i].z);
}
}
for (i = 1; i <= n; i++)
maxn = maxn > h[i] ? maxn : h[i];
printf("Case %d: maximum height = %d\n", c, maxn);
}
return 0;
}
总结:
做了一些dp题,发现在数组上的dp都很类似(不是专业ACM,不知道这种题型叫什么)。