思路:
直接状压乱写,设一堆状态
c o d e code code
#include<iostream>
#include<cstdio>
using namespace std;
int n;
int a[18], b[18], c[18];
int f[32800][16][3][2];
int ans=0;
//0->a*b
//1->a*c
//2->b*c
//0->横放
//1->直放
int main()
{
scanf("%d", &n);
for(register int i=1; i<=n; ++i)
scanf("%d%d%d", &a[i], &b[i], &c[i]),
f[1<<i-1][i][0][0]=f[1<<i-1][i][0][1]=c[i],
f[1<<i-1][i][1][0]=f[1<<i-1][i][1][1]=b[i],
f[1<<i-1][i][2][0]=f[1<<i-1][i][2][1]=a[i];
for(register int i=1; i<1<<n; ++i)
{
for(register int j=n; j>=1; --j)
{
if((i&(1<<j-1))==0)
continue;
register int s1=i-(1<<j-1);
for(register int s=2; s>=0; --s)
{
for(register int r=1; r>=0; --r)
{
register int chang, kuan, gao;
if(r==0)
{
if(s==0)
chang=a[j], kuan=b[j], gao=c[j];
if(s==1)
chang=a[j], kuan=c[j], gao=b[j];
if(s==2)
chang=b[j], kuan=c[j], gao=a[j];
}
else
{
if(s==0)
chang=b[j], kuan=a[j], gao=c[j];
if(s==1)
chang=c[j], kuan=a[j], gao=b[j];
if(s==2)
chang=c[j], kuan=b[j], gao=a[j];
}
for(register int k=n; k>=1; --k)
{
if((s1&(1<<k-1))==0)
continue;
if(a[k]<=chang&&b[k]<=kuan&&f[i][j][s][r]<f[s1][k][0][0]+gao)
f[i][j][s][r]=f[s1][k][0][0]+gao;
if(b[k]<=chang&&a[k]<=kuan&&f[i][j][s][r]<f[s1][k][0][1]+gao)
f[i][j][s][r]=f[s1][k][0][1]+gao;
if(a[k]<=chang&&c[k]<=kuan&&f[i][j][s][r]<f[s1][k][1][0]+gao)
f[i][j][s][r]=f[s1][k][1][0]+gao;
if(c[k]<=chang&&a[k]<=kuan&&f[i][j][s][r]<f[s1][k][1][1]+gao)
f[i][j][s][r]=f[s1][k][1][1]+gao;
if(b[k]<=chang&&c[k]<=kuan&&f[i][j][s][r]<f[s1][k][2][0]+gao)
f[i][j][s][r]=f[s1][k][2][0]+gao;
if(c[k]<=chang&&b[k]<=kuan&&f[i][j][s][r]<f[s1][k][2][1]+gao)
f[i][j][s][r]=f[s1][k][2][1]+gao;
}
}
}
}
}
for(register int i=(1<<n)-1; i>=1; --i)
for(register int j=n; j>=1; --j)
if(i&(1<<j-1))
for(register int k=2; k>=0; --k)
for(register int r=1; r>=0; --r)
if(ans<f[i][j][k][r])
ans=f[i][j][k][r];
printf("%d", ans);
return 0;
}