NOIP2016提高組模擬 積木

2021-07-22 09:00:18 字數 3187 閱讀 9172

比賽的時候用了個神奇的小暴力,本來打算拿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分 我們容易發現峰一定是最大的那個數,我們把峰放到每乙個位置上,然後在往峰的左邊隨便填一些數,每種填數的方法...