题意:给定n个箱子的长宽高,可互换,现在来堆箱子,要求下面的长宽一定要大于上一个的长宽,求最大高度。
思路:首先是把各种情况的箱子保存起来:简单分析可得,每行数据可对应三种高,可人为定义长小于宽(x<y),之后只要使得下层长宽分别小于上层即可(小对小,大对大)。接下来对所有情况从小到大排序,x相等排y。dp[i]表示第i个情况的箱子为底层时可堆得的最大高度。
dp [ i ] = dp [ j ] + box [ i ] .z
最后选出最大的dp[i],即选底层的箱子。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <algorithm>
#include <cstring>
#include <utility>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
int n,sum,cas=0,b[3],dp[100];
struct node
{
int x,y,z;
}box[100];
bool cmp(node a,node b) //先排x,再排y
{
if(a.x==b.x)
return a.y<b.y;
else
return a.x<b.x;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
int num=0,sum=0;cas++;
while(n--)
{
scanf("%d%d%d",&b[0],&b[1],&b[2]); //放到数组里好排序,可以减少多余运算
sort(b,b+3);
box[num].x=b[0],box[num].y=b[1],box[num++].z=b[2]; //保证x<=y
box[num].x=b[1],box[num].y=b[2],box[num++].z=b[0];
box[num].x=b[0],box[num].y=b[2],box[num++].z=b[1];
}
sort(box,box+num,cmp); //必须 从小到大 排序好箱子
for(int i=0;i<num;i++)
dp[i]=box[i].z; //初始化底层高度
for(int i=1;i<num;i++)
for(int j=0;j<i;j++)
{
if(box[j].x<box[i].x && box[j].y<box[i].y) //满足题意条件
if(dp[i]<dp[j]+box[i].z)
dp[i]=dp[j]+box[i].z; //更新
}
for(int i=0;i<num;i++)
sum=max(sum,dp[i]);
printf("Case %d: maximum height = %d\n",cas,sum);
}
return 0;
}
搞明白了就简单了。