题目
Description
Input
Sample Input
3
8 7 6
3 9 4
1 10 5
Output
Sample Output
18
Data Constraint
题目大意
给你一些方块,给出每个方块的长宽高,可以以任意一面为底面,用任意的顺序选择任意一些方块,下面的方块一定要完全包含上面的方块(下面方块的长,宽分别小于上面方块的长宽)。求最高的搭出积木的高度
比赛时の想法
看到这个数据范围,就想到状压DP,状态也是很好设的,我们设f[s,i,j,k]表示当前方块的选取状态为s,当前在最上面的方块是i,它的长和宽分别是j和k(由于一个方块只有3个长度,所以j,k的范围都是1-3的)。转移的话也很简单,我们先确定要添加的一个方块,然后再确定当前在最上面的方块,最后再确定两个方块以哪一位为底面就可以了。那么时间复杂度
正解
在上面
贴代码
var
f:array[0..65540,1..15,1..3,1..3]of longint;
a:array[0..15,1..3]of longint;
g:array[0..20]of longint;
i,j,k,l,n,x,y,ans:longint;
function max(x,y:longint):longint;
begin
if x>y then exit(x) else exit(y);
end;
procedure init;
begin
g[1]:=1;
for i:=2 to 20 do g[i]:=g[i-1]*2;
readln(n);
for i:=1 to n do
begin
readln(a[i,1],a[i,2],a[i,3]);
f[g[i],i,1,2]:=a[i,3];
f[g[i],i,1,3]:=a[i,2];
f[g[i],i,2,3]:=a[i,1];
f[g[i],i,2,1]:=a[i,3];
f[g[i],i,3,1]:=a[i,2];
f[g[i],i,3,2]:=a[i,1];
end;
end;
begin
init;
for i:=1 to g[n+1]-2 do
begin
for j:=1 to n do
if g[j] and i=0 then
begin
for k:=1 to n do
if g[k] and i<>0 then
begin
for x:=1 to 3 do
begin
for y:=1 to 3 do
if x<>y then
begin
if (a[j,1]<=a[k,x]) and (a[j,2]<=a[k,y]) and (f[i,k,x,y]>0) then
f[i+g[j],j,1,2]:=max(f[i+g[j],j,1,2],f[i,k,x,y]+a[j,3]);
if (a[j,2]<=a[k,x]) and (a[j,1]<=a[k,y]) and (f[i,k,x,y]>0) then
f[i+g[j],j,2,1]:=max(f[i+g[j],j,2,1],f[i,k,x,y]+a[j,3]);
if (a[j,1]<=a[k,x]) and (a[j,3]<=a[k,y]) and (f[i,k,x,y]>0) then
f[i+g[j],j,1,3]:=max(f[i+g[j],j,1,3],f[i,k,x,y]+a[j,2]);
if (a[j,3]<=a[k,x]) and (a[j,1]<=a[k,y]) and (f[i,k,x,y]>0) then
f[i+g[j],j,3,1]:=max(f[i+g[j],j,3,1],f[i,k,x,y]+a[j,2]);
if (a[j,2]<=a[k,x]) and (a[j,3]<=a[k,y]) and (f[i,k,x,y]>0) then
f[i+g[j],j,2,3]:=max(f[i+g[j],j,2,3],f[i,k,x,y]+a[j,1]);
if (a[j,3]<=a[k,x]) and (a[j,2]<=a[k,y]) and (f[i,k,x,y]>0) then
f[i+g[j],j,3,2]:=max(f[i+g[j],j,3,2],f[i,k,x,y]+a[j,1]);
end;
end;
end;
end;
end;
for i:=1 to g[n+1]-1 do
begin
for j:=1 to n do
for x:=1 to 3 do
for y:=1 to 3 do
if x<>y then
begin
if f[i,j,x,y]>ans then ans:=f[i,j,x,y];
end;
end;
writeln(ans);
end.