您的位置:首页 > 其它

【NOIP2016提高A组模拟9.2】积木

2016-09-03 09:13 295 查看

题目

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的)。转移的话也很简单,我们先确定要添加的一个方块,然后再确定当前在最上面的方块,最后再确定两个方块以哪一位为底面就可以了。那么时间复杂度O(2n−1∗n2∗9)

正解

在上面

贴代码

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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: