比賽的時候用了個神奇的小暴力,本來打算拿40分,沒想到暴力出奇蹟,隨機資料下表現優良,居然碾過去了。暴力方法不講,只貼**,僅供對拍。
正解顯然要用狀態壓縮(看資料範圍),設fs
,i,0
/1/2
,s表示當前已選擇的積木集合,i表示在最上方的積木編號,0/1/2表示最上方的積木哪面朝上。轉移方程容易推導。
暴力
var
a:array[0..15,0..3] of longint;
fx:array[1..3,1..2] of longint=((1,2),(2,3),(1,3));
g:array[1..3] of longint=(3,1,2);
p:array[1..15] of boolean;
n,i,j,k,ans:longint;
function
max(x,y:longint):longint;
begin
if x>y then
exit(x) else
exit(y);
end;
procedure
dfs(x,high,l,r:longint);
var i,j:longint;
begin
if x=0
then
exit;
for i:=1
to n do
if p[i]=false
then
begin
p[i]:=true;
for j:=1to3
doif (l>=a[i,fx[j,1]])and(r>=a[i,fx[j,2]]) then
begin
ans:=max(ans,high+a[i,g[j]]);
dfs(x-1,high+a[i,g[j]],a[i,fx[j,1]],a[i,fx[j,2]]);
end;
p[i]:=false;
end;
end;
begin
readln(n);
for i:=1
to n do
begin
for j:=1to3
doread(a[i,j]);
readln;
for j:=1to2
dofor k:=j+1to3
doif a[i,j]>a[i,k] then
begin
a[i,0]:=a[i,j];a[i,j]:=a[i,k];a[i,k]:=a[i,0];
end;
end;
dfs(n,0,maxlongint,maxlongint);
writeln(ans);
end.
正解var
s,i,j,k,jj,n,x,y,xx,yy,z,temp,ans:longint;
a:array[1..15,1..3] of longint;
f:array[0..100000,1..15,1..3] of longint;
mi:array[0..15] of longint;
procedure
max(var x:longint;y:longint);
begin
if y>x then x:=y;
end;
procedure
fu(i,j:longint;var x,y:longint);
begin
case j of
1:begin x:=a[i,2]; y:=a[i,3]; end;
2:begin x:=a[i,1]; y:=a[i,3]; end;
3:begin x:=a[i,1]; y:=a[i,2]; end;
end;
end;
procedure
swap
(var x,y,z:longint);
begin
if xthen
begin temp:=x;x:=y;y:=temp; end;
if xthen
begin temp:=x;x:=z;z:=temp; end;
if ythen
begin temp:=y;y:=z;z:=temp; end;
end;
begin
read(n);
mi[0]:=1; for i:=1
to n do mi[i]:=mi[i-1]*2;
for i:=1
to n do
begin
read(x,y,z); swap(x,y,z);
a[i,1]:=x; a[i,2]:=y; a[i,3]:=z;
end;
for i:=1
to n do
begin f[mi[i-1],i,1]:=a[i,1]; f[mi[i-1],i,2]:=a[i,2];
f[mi[i-1],i,3]:=a[i,3]; end;
for s:=1
to mi[n]-1
dofor i:=1
to n do
for j:=1to3
doif f[s,i,j]>0
then
begin
max(ans,f[s,i,j]);
fu(i,j,x,y);
for k:=1
to n do
if mi[k-1] and s=0
then
for jj:=1to3
dobegin
fu(k,jj,xx,yy);
if (x>=xx) and (y>=yy) then
max(f[s+mi[k-1],k,jj],f[s,i,j]+a[k,jj])
end;
end;
writeln(ans);
end.
NOIP2016提高A組模擬9 2 積木
給你一些方塊,給出每個方塊的長寬高,可以以任意一面為底面,用任意的順序選擇任意一些方塊,下面的方塊一定要完全包含上面的方塊 下面方塊的長,寬分別小於上面方塊的長寬 求最高的搭出積木的高度 看到這個資料範圍,就想到狀壓dp,狀態也是很好設的,我們設f s,i,j,k 表示當前方塊的選取狀態為s,當前在...
計數 NOIP2016提高A組模擬7 15
樣例輸入 2 10 樣例輸出 90資料範圍 剖解題目 題目說的很明了了。思路 求方案數,一般會設計道dp,規律之類的。解法 數字dp,設f i j 表示當前到了第i位,這一位的數字是j的方案數。自然有 f i j f i 1 l f i j 0 l k 且 l 0 and j 0 看到這位數,很明顯...
NOIP2016提高A組模擬9 2 單峰
問1 n,n個數的全排列中有多少個滿足單峰序列的性質,並把答案mod 1e9 7 這題還是很簡單的,一開始打了乙個50分的做法,然後發現答案就是2n 1,然後沒有發現輸入也會爆,於是就得了50分 我們容易發現峰一定是最大的那個數,我們把峰放到每乙個位置上,然後在往峰的左邊隨便填一些數,每種填數的方法...