SPFA 記憶化搜尋 傳送爸爸

2021-10-23 17:38:38 字數 2598 閱讀 5373

輸入檔案第一行包括兩個整數:地圖的行數r和列數c.接下來的r行描述這個地圖.每一行包括c個字元:#,.,s或c(含義已在上文描述)

輸出乙個整數——從你現在位置出發到達爸爸的位置所需要的最少時間.

很簡單能想到bfs

一開始我做的是現向四個方向走一格

然後再向四個方向走到盡頭(傳送門)(並沒有判斷附近是否有牆)

然後後來改的時候可能是對dal

aodalao

dala

o的思路有一些誤解

spfa建圖時只判斷了如果乙個點的四個方向如果有牆

才能走傳送門到乙個方向的盡頭(改了幾個小時,然後發現是偽正解時,心態直接崩了)

然後開始正解:

spfa照樣(應該不用多講了吧)

只是建圖麻煩

每個點有兩個要連

乙個是四個方向走一格

另乙個就是四個方向走到盡頭

乙個傳送門放路的盡頭的牆上

那另乙個傳送門呢?

就要找離這個點最近的乙個點

我的方法時朝四個方向走

然後在四個值中取min

就是走傳送門的最小代價

在求乙個點某方向的盡頭時

需要記憶化

否則時間會炸

#include

#include

#include

#include

#include

using

namespace std;

const

int dx[5]

=;const

int dy[5]

=;int bol[

10000005

], m[

1005][

1005

], dis[

10000005

], h[

10000005

], get[5]

, d[

10000005][

5], f[

10000005][

5];int n, m, ans, start, end, t, tot;

char c;

struct wh_

wh[10000005];

char

read()

//交洛谷時要加這個|洛谷資料比較狗(doge)

bool

check

(int x,

int y)

//判斷是否有牆

void

spfa

(int k)

} bol[l]=0

;}}voidhw(

int x,

int y,

int z)

; h[x]

= tot;

}int

dfs(

int x,

int y,

int k)

if(d[m[x]

[y]]

[k])

//記憶化

int l =

dfs(xx, yy, k)+1

; d[m[x]

[y]]

[k]= d[m[xx]

[yy]

][k]

;return

(f[m[x]

[y]]

[k]= l);}

intmain()

}for

(int i =

1; i <= n;

++i)

for(

int j =

1; j <= m;

++j)

if(m[i]

[j])

//若是空地

for(

int k =

1; k <=4;

++k)

//傳送門

if(get[k]

!= m[i]

[j])

hw(m[i]

[j], get[k]

, min);}

spfa

(start)

;printf

("%d"

, dis[end]);

return0;

}

記憶化搜尋

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

記憶化搜尋

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

記憶化搜尋

原文 感謝作者。一.動態規劃 動態規劃 dynamic programming 與 分治思想 有些相似,都是利用將問題分 為子問題,並通過合併子問題的解來獲得整個問題的解。於 分治 的不同之處在 於,對於乙個相同的子問題動態規劃演算法不會計算第二次,其實現原理是將每乙個計算過的子問題的值儲存在乙個表...