积木
小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; }