积木

X 感到很无聊,从柜子里翻出了他小时候玩的积木, 这套积木共有 n 块,每块积木都是1个长方体。小X 想用这些积木拼成1个积木塔(不必每块 积木都使用, 所谓积木塔,就是将积木1个1个摞起来,(除去最底层的积木外)每块积木的底下必须能被它下面 的积木的底面完全包含(即对应的长宽都要更小或相等)。当然,积木可以任意放置,即可以以任意一面 作为底面。 现在小X 想知道,积木塔最大能拼多高。 

Input

第⼀⾏包含⼀个整数 n。 接下来 n ⾏,每⾏包含三个整数 a; b; c,表⽰该块积木是⼀个 a × b × c 的长⽅体。

Output

第⼀⾏包含⼀个整数,表⽰答案。

正解状压 写的爆搜 qwq

个人感觉爆搜比较好理解,就不再赘余,代码里有部分讲解

#include<cstdio>
using namespace std;

inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
   return s*w;
}
struct node{int z[4],x[4],y[4];}az[16];//分别枚举每个边做长宽高 xyz长宽高 
int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
int n,ans=-1,x,y,z,vis[16];//vis标记是否来过 
void init(){
    n=read();
    for(int i=1;i<=n;i++)
    {
        x=read(),y=read(),z=read();
        az[i].x[1]=min(x,y);az[i].y[1]=max(x,y);az[i].z[1]=z;//分别枚举 
        az[i].x[2]=min(y,z);az[i].y[2]=max(y,z);az[i].z[2]=x;
        az[i].x[3]=min(x,z);az[i].y[3]=max(x,z);az[i].z[3]=y;
    }
}
void dfs(int z,int x,int y)
{    ans=max(ans,z);//更新高度 
    for(register int i=n;i>=1;i--)
        if(!vis[i])//没有选过 
        {    vis[i]=1;
            for(register int j=1;j<=3;j++)
                if(az[i].x[j] <= x && az[i].y[j] <= y)
                    dfs(z + az[i].z[j],az[i].x[j],az[i].y[j]);
            vis[i]=0;
        }
    }
int main()
{
    init();
    if(n==1){printf("%d",max(x,max(y,z)));return 0;}
    for(int i=1;i<=n;i++){    
        vis[i]=1;//走过第一块物块 
        for(int j=1;j<=3;j++)
            dfs(az[i].z[j],az[i].x[j],az[i].y[j]);//dfs(h,x,y) 
        vis[i]=0;
        }
    printf("%d",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/shikeyu/p/13260457.html