NOIP2015提高組Day1鬥地主

2021-07-08 15:42:44 字數 3518 閱讀 9261

仔細看,這道題著實想不到什麼優美的演算法,那麼基本確定方向——dfs。

先分析,這題的花色是沒用的

我們再分析,會發現這題的出牌順序是不影響答案的

那麼我們便可以先出牌多的(因為這樣答案便會先便小,那麼便可以方便後面的剪枝)

也就是我們先打順子再打帶牌!

順子是沒有什麼技巧的,便直接暴搜(當然也是先暴搜長度長的)

帶牌是有技巧的!

我們發現帶牌是不與牌本身的點數有關的

於是我們便可以分別統計有多少種牌是四張的,三張的,兩張的,一張的。

最後注意三點:

1.我們可以拆開牌來打

也就是若我想打四帶兩張單張牌

我們便可以拆三張的拆成兩張的和一張的。

或者兩張一張的,或者一張兩張的。

2.王是不能帶出去的,也就是對王是單獨出的。

3.2,王是不能順子的

這樣便可以放心的暴搜了。

var

n,t,x,y,i,ans:longint;

a:array[0..15] of longint;

p:array[0..4] of longint;

toe:array[1..3] of longint=(5,3,2);

procedure

dfs(an:longint);

var i,j:longint;

begin

if an>=ans then

exit;j:=0;

for i:=1to4

do j:=j+p[i];

if j+anthen ans:=j+an;

if p[4]>0

then

begin

dec(p[4]);

for i:=4

downto2do

if p[i]>0

then

begin

dec(p[i]);inc(p[i-2]);

for j:=2to4

doif p[j]>0

then

begin

dec(p[j]);inc(p[j-2]);

dfs(an+1);

inc(p[j]);dec(p[j-2]);

end;

inc(p[i]);dec(p[i-2]);

end;

for i:=1to4

doif p[i]>0

then

begin

dec(p[i]);inc(p[i-1]);

for j:=1to4

doif p[j]>0

then

begin

dec(p[j]);inc(p[j-1]);

dfs(an+1);

inc(p[j]);dec(p[j-1]);

end;

inc(p[i]);dec(p[i-1]);

end;

i:=i;

inc(p[4]);

end;

if p[3]>0

then

begin

dec(p[3]);

for i:=2to4

doif p[i]>0

then

begin

dec(p[i]);inc(p[i-2]);dfs(an+1);inc(p[i]);dec(p[i-2]);

end;

for i:=1to4

doif p[i]>0

then

begin

dec(p[i]);inc(p[i-1]);dfs(an+1);inc(p[i]);dec(p[i-1]);

end;

inc(p[3]);

end;

end;

procedure

solve

(an:longint);

var i,j,k,jj:longint;

begin

if an>=ans then

exit;

fillchar(p,sizeof(p),0);

for i:=1

to15

do inc(p[a[i]]);

if p[0]=15

then

begin

ans:=an;exit;

end;

dfs(an);

for k:=1to3

dobegin

for i:=1

to14-toe[k]-1

doif a[i]>=k then

begin

for j:=i+1

to12

doif a[j]then

break;

if a[j]then dec(j);

if j-i+1

then

continue;jj:=j;

for j:=i to i+toe[k]-1

do dec(a[j],k);

solve(an+1);

for j:=i+toe[k] to jj do

begin

dec(a[j],k);

solve(an+1);

end;

for j:=i to jj do inc(a[j],k);

end;

i:=i;

end;

end;

begin

readln(t,n);

for t:=1

to t do

begin

ans:=13;

fillchar(a,sizeof(a),0);

for i:=1

to n do

begin

readln(x,y);

if (x>=3)and(x<=13) then inc(a[x-2])

else

if x=1

then inc(a[12])

else

if x=2

then inc(a[13])

else

if y=1

then inc(a[14]) else inc(a[15]);

end;

if (a[14]>0)and(a[15]>0) then

begin

a[14]:=0;a[15]:=0;

solve(1);

a[14]:=1;a[15]:=1;

end;

solve(0);

writeln(ans);

end;

close(input);close(output);

end.

NOIP2015提高組Day1 資訊傳遞

問題描述 有n個同學 編號為1到n 正在玩乙個資訊傳遞的遊戲。在遊戲裡每人都有乙個固定的資訊傳遞物件,其中,編號為i的同學的資訊傳遞物件是編號為ti的同學。遊戲開始時,每人都只知道自己的生日。之後每一輪中,所有人會同時將自己當前所知的生日資訊告訴各自的資訊傳遞物件 注意 可能有人可以從若干人那裡獲取...

NOIP2015提高組Day1 鬥地主

這道題做的時候讓我幾近崩潰,因為如果要打暴力的話太煩了不想打 但是我們發現 這樣只要判斷前六種方法就行了,打幾個判斷,30 首先,做一下基本處理 簡化題目 因為一般的鬥地主除了大王小王,沒有花色的大小區別,但這裡也不是讓你贏,只是自己乙個人快速打光牌。我們發現花色並沒有什麼用,可以免去。所以我們我們...

NOIP2015提高組Day1 神奇的幻方

問題描述 幻方是一種很神奇的 n n矩陣 它由數字1,2,3,n n 構成,且每行 每列及兩條對角線上的數字之和都相同。當n為奇數時,我們可以通過以下方法構建乙個幻方 首先將1寫在第一行的中間。之後,按如下方式從小到大依次填寫每個數k k 2,3,n n 1.若 k 1 在第一行但不在最後一列,則將...