銀河之星 (亂搞 記憶化搜尋)

2022-05-03 17:18:10 字數 1810 閱讀 3850

乍一看真的無從下手,規則一臉懵逼。

首先看到第3個規則,每個棋子往任意方向都只能走3格。可以聯想一下西洋棋四個象,2個永遠在黑格,2個永遠在白格。

依照這個思路,我們只有9類位置(橫座標模3與縱座標模3都相同的位置為同一類)。

其中,每一類位置上的棋子可以通過規則3互達同一類位置,卻永遠不可能用規則3走到其他類的位置。

如下圖:(想象若干個3x3的框,左上角對齊鋪滿整個地圖,框內位置相同的即同類位置)

我們把同類位置的棋子數量求和一下,對應放到乙個3x3的九宮格裡(我們按照上圖以0~8為每類位置編號)。以下就只對這個九宮格操作就可以了,比如$x$個0類的棋子越過1個8類棋子到達4類位置,我們把0的數字減$x$,把8的數字減$x$,把4的數字加$x$。

為什麼不用考慮實際上棋子的位置呢?

根據上面標紅的性質,任意同類棋子可以互達。我不需要考慮我要操作的3枚棋子具體在什麼地方,只要將這3枚棋子移到三點一線,就可以進行規則2的操作了。

然而不是每三個位置都能移成三點一線的,受地圖大小影響,可能會出現這種情況:

比如這個案例,對於7-->8-->6的情況,我能用九宮格的數字相加減嗎?7-->5-->0呢?都不行。因為實際地圖上,並不存在乙個786、750三點一線的地方。

但是0-->6-->3、1-->7-->4、0-->7-->5都是可以用九宮格的數字進行加減操作的,因為地圖的確存在這種場所可以供棋子移動過來進行操作

那麼我們預處理出那些類別的位置可以走2步互達(列舉原圖的位置往八個方向走2步看看走到的是什麼類別的位置)。

考慮到棋子總數只有10,我們可以用狀態壓縮記錄這個九宮格的狀態,暴力列舉即可,用map記憶一下有沒有到過這個狀態。

終止狀態即:指定終點同類位置的權值為1,且其他位置權值為0.

1 #include 2 #include 3

#define min(a,b) (a4

using

namespace

std;

5 typedef long

long

ll;6

const

intbase=11,xx[8]=,yy[8]=;

7int

k,n,m,x0,y0;

8int can[9][9

];9 ll bin[10

],bigsta,finsta;

10 mapint>ans;

11 inline int trans(int x)

12void

getdirection()25}

26}27bool

dfs(ll s)

36int

u,v,p,x,y,px,py;

37for(int i=0;i<3;i++)

38for(int j=0;j<3;j++)50}

51 ans[s]=2;52

return

false;53

}54intmain()

68if(dfs(bigsta)) printf("

yes\n");

69else printf("

no\n");

70}71return0;

72 }

奇妙**

銀河之星 記憶化搜尋 9點染色

problem 3 銀河之星 galaxy.cpp c pas 資料組數不超過10.這題就是記憶化搜尋 9點染色減少狀態,map記憶化 b i j k 表示棋子可否從k方向到 i,j include include include include include include include in...

記憶化搜尋

演算法上依然是搜尋的流程,但是搜尋到的一些解用 動態規劃 的那種思想和模式作一些儲存。一般說來,動態規劃總要遍歷所有的狀態,而搜尋可以排除一些無效狀態。更重要的是搜尋還可以剪枝,可能剪去大量不必要的狀態,因此在空間開銷上往往比動態規劃要低很多。記憶化演算法在求解的時候還是按著自頂向下的順序,但是每求...

記憶化搜尋

記憶化搜尋 演算法上依然是搜尋的流程,但是搜尋到的一些解用動態規劃的那種思想和模式作一些儲存。記憶化演算法在求解的時候還是按著自頂向下的順序,但是每求解乙個狀態,就將它的解儲存下來,以後再次遇到這個狀態的時候,就不必重新求解了。例1.題目描述 給從左至右排好隊的小朋友們分糖果,要求 1.每個小朋友都...