百練 4124 狀態壓縮 記憶化搜尋

2021-08-05 23:38:40 字數 1064 閱讀 3080

傳送門

//題意就不說了.

//題目要求是一定是從標號1出發, 最後到達標號n, 中間不重複的經過完其他島. 那麼問題就是如何搜尋. 中間有14個點, 那麼最壞的情況就是14!中情況, 這樣肯定是會超時的. 所以我們需要剪枝, 因為我們可以發現中途到達某個點時, 如果此時的深度大於了曾經經過的點的深度或者目標點的深度, 那麼直接沒有搜尋下去的必要.

所以我們需要記憶化搜尋.

還有乙個問題就是如何用state表示當前已經經過了的點的關係 , 因為必須保證中間的島都要經歷過.

所以我們可以用二進位制來表示. 例如 : 111 表示從1島到2再到3. 101 表示從1島到3. 所以目標狀態就是(1<

const

int inf= 0x3f3f3f3f; //只有當inf取這個值時才能直接memset.

int n,endstate;

const

int maxn = 20;

int dp[maxn][(1

<<16)+5]; //最多的狀態.

int a[maxn][maxn]; //存的距離關係.

void dfs(int u,int d,int state) //記憶化搜尋.

if(d >= dp[u][state] || d >= dp[n][endstate]) return ; //剪枝

dp[u][state] = d;

int i,j;

for(i=2,j=2;i1) //最後乙個點需要特殊判斷, 因為必須是最後到達第n個點.

//而之前不能到達過最後乙個點,所以需要特殊判斷.

if(state == endstate ^ 1) dfs(i,d+a[u][i],state | j);

}void solve()

}fill(dp,inf); //初始化為最大值.

endstate = ( 1

<1; //把目標狀態算出來.

dfs(1,0,1);

printf("%d\n",dp[n][endstate]);

}}

交換遊戲 狀態壓縮 記憶化搜尋

題目描述 一列上有12個孔,這12個孔中有些孔被遮擋住了。假定我們用 來表示沒被遮擋住的孔,用 o 來表示被遮擋住的孔。如果相鄰的三個孔有兩個孔被遮擋,並且被遮擋的兩個孔相鄰,就是 oo 和 oo 對於這樣的三個孔,我們可以將中間的孔的遮擋物移開,代價是將一端的遮擋物移到另一端沒有被遮擋的孔上面。對...

uva 11008 狀態壓縮 記憶化搜尋

這題屬於狀態壓縮dp中比較基礎的一題,經過仔細分析後我們發現此題雖然座標範圍較大,但是點比較少最多才16個很容易想到用狀態壓縮。dp x 表示當前樹的狀態最少要轉移的次數 砍的次數 具體狀態轉移由於他狀態轉移的順序比較亂所以用的是記憶化搜尋。起始狀態是 1 如下 1 include 2 includ...

模板題 數字DP 狀態壓縮 記憶化搜尋

dp啊!難的真難,簡單的也真簡單,正讓人哭笑不得,喜憂參半 完全揹包解法 狀態表示 f i j 表示只從1 i中選,且總和等於j的方案數 狀態轉移方程 f i j f i 1 j f i j i include using namespace std const int n 1010 mod 1e9...