开私服传奇做网站需要钱嘛/代运营服务
DescriptionDescriptionDescription
只能堆一次的堆箱子
n≤15n\leq 15n≤15
SolutionSolutionSolution
看到nnn,直接状压dpdpdp
设f[s][i][k]f[s][i][k]f[s][i][k]表示状态为sss,下面的为iii,目前是第kkk种摆放方式
得到方程f[t][j][l]=max{f[s][i][k]+c[i]}f[t][j][l]=max\{f[s][i][k]+c[i]\}f[t][j][l]=max{f[s][i][k]+c[i]}
然后就workoutwork\ outwork out了
CodeCodeCode
#include <cstdio>
#include <algorithm>
#define A d[l][0]
#define B d[l][1]
#define C d[k][0]
#define D d[k][1]
using namespace std;int n,f[32768][16][3],a[16][3],ans;
bool check(int a,int b,int c,int d){return a>=c&&b>=d||a>=d&&b>=c;}
const int d[3][2]={{0,1},{0,2},{1,2}};
signed main()
{scanf("%d",&n);for(register int i=1;i<=n;i++) scanf("%d%d%d",&a[i][0],&a[i][1],&a[i][2]);for(register int s=0;s<(1<<n);s++)for(register int i=1;i<=n;i++)for(register int j=1;j<=n;j++)if(!((s>>(j-1))&1))for(register int k=0;k<3;k++){int t=s|(1<<(j-1));for(register int l=0;l<3;l++)if(check(a[j][A],a[j][B],a[i][C],a[i][D]))f[t][j][l]=max(f[t][j][l],f[s][i][k]+a[j][2-l]);}for(register int s=0;s<(1<<n);s++)for(register int i=1;i<=n;i++)for(register int j=0;j<3;j++)ans=max(ans,f[s][i][j]);printf("%d",ans);
}