17年4月20
/*******c0de*******/
我们很容易将此问题与最大下降子列问题联系起来,即求满足要求的最大高度。
首先要明白:
在原始的最大子列问题中 给出的数列即为要求的顺序(即这个子列肯定是自前向后找)
也就是说,后面的数只能找前面比它大的数,而不能找后面比它打的书
但此问题,给出的木板长短是任意的,因此我们先必须对其进行排序,使得排序之后的木板(对应原始问题的数列)满足后面的木板只能放在前面木板的上方,而不能放在后面木板的上方
解决这个问题相对就容易了,我们只需要将所有情况的木板按照其宽(或者长 这里自己规定即可) 按从大到小的顺序排列,即可满足前面的木板绝对不可以放在后面木板的上方,此时将问题已经转化为了原始问题,套用模版即可。
代码如下
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;//只需要保证前面的不会放在后面的上面即可。 后面的可能会放在前面上面 转化为最大下降子序列。
struct no
{
int a;//长
int b;//宽
int h;//高
int l;//从第一个木板到此木板的最大高度
}num[1000];
bool cmp(no x,no y)//先按照行/列的顺序降序排列,保证前面不能放在后面,如果有行一样的,不用管,因为他们之间不存在相互放置的关系。
{
return x.a > y.a;
}
int main()
{
int n;
int p = 0;
while(scanf("%d",&n)!=EOF&&n)
{
int i;
int x,y,z;
int k = -1;
for(i = 0; i < n; i++)//一共有六种情况 将它们全部存储
{
scanf("%d%d%d",&x, &y, &z);
num[++k].h = x, num[k].a = y, num[k].b = z, num[k].l = x;
num[++k].h = x, num[k].a = z, num[k].b = y, num[k].l = x;
num[++k].h = y, num[k].a = z, num[k].b = x, num[k].l = y;
num[++k].h = y, num[k].a = x, num[k].b = z, num[k].l = y;
num[++k].h = z, num[k].a = x, num[k].b = y, num[k].l = z;
num[++k].h = z, num[k].a = y, num[k].b = x, num[k].l = z;
}
sort(num,num + k + 1,cmp);//排序
int j;
for(i = 0; i <= k; i++)
{
for(j = 0; j < i; j++)
{
if((num[j].a > num[i].a&&num[j].b > num[i].b)&&(num[j].l + num[i].h > num[i].l))
num[i].l = num[j].l + num[i].h;
}
}
int maxn = -1;//找最大的高度
for(i = 0; i <= k; i++)
{
if(num[i].l > maxn) maxn = num[i].l;
}
printf("Case %d: maximum height = %d\n",++p,maxn);
}
return 0;
}