版权声明:原创,未经作者允许禁止转载 https://blog.csdn.net/Mr_wuyongcong/article/details/88364143
正题
题目大意
有长方体积木 块,求能搭成的最高高度。
解题思路
考虑状态压缩,设 表示积木使用状态为 ,最下面的是第 块,状态为 :
状态:对于一个长方体
- 的底
- 的底
- 的底
首先枚举状态,然后枚举当前放哪个,然后枚举上次放哪个,然后枚举最上面哪个的放置状态,然后暴力动态转移。
时间复杂度
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=17;
struct node{
int a,b,c;
}c[N];
int f[1<<N][N][3],MS,n,ans;
bool check(int x,int y,int l,int w)
{return x>=l&&y>=w||x>=w&&y>=l;}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d%d",&c[i].a,&c[i].b,&c[i].c);
MS=(1<<n);
for(int s=0;s<MS;s++)
{
for(int i=1;i<=n;i++){
if(s&(1<<(i-1))) continue;
int mb=s|(1<<(i-1));
for(int j=1;j<=n;j++)
for(int k=0;k<3;k++)
{
int l,w;
if(k==0) l=c[j].a,w=c[j].b;
else if(k==1) l=c[j].a,w=c[j].c;
else l=c[j].b,w=c[j].c;
if(check(c[i].a,c[i].b,l,w))
f[mb][i][0]=max(f[mb][i][0],f[s][j][k]+c[i].c);
if(check(c[i].a,c[i].c,l,w))
f[mb][i][1]=max(f[mb][i][1],f[s][j][k]+c[i].b);
if(check(c[i].b,c[i].c,l,w))
f[mb][i][2]=max(f[mb][i][2],f[s][j][k]+c[i].a);
}
}
}
//1-a*b 2-a*c 3-b*c
for(int i=1;i<=n;i++)
for(int k=0;k<3;k++)
ans=max(ans,f[MS-1][i][k]);
printf("%d",ans);
}