使用廣度優先搜尋,dp[key][x][y]表示在擁有鑰匙key並在座標(x,y)時需要的最少的步數,key的二進位制的第i位等於1則代表擁有第i把鑰匙。
需要注意以下幾點:
1.可能存在同一座標有多把鑰匙。
2.牆和門是在兩個座標間進行移動時的障礙,並不在座標點上,因此兩個方向的移動都要加入wall陣列。
2.可以使用方向陣列來進行上下左右的搜尋。
3.搜尋到座標(n,m)時記錄最小步數並退出搜尋。
**如下:
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8view code#define maxp 11
9#define maxn 51
10using
namespace
std;
11int bin = ;
12int dir[4][2]=, , , };//
左,上,右,下
13int dp[2050
][maxn][maxn];
14int
key[maxn][maxn];
15int
wall[maxn][maxn][maxn][maxn];
16int
n, m, p;
17class
state18;
22void
solve()
2344
state next;
45 next.x = cur.x + dir[i][0
];46 next.y = cur.y + dir[i][1
];47 next.key = 0
;48 next.step = 0;49
//出界
50if( next.x < 1 || next.x > n ) continue;51
if( next.y < 1 || next.y > m ) continue;52
int w =wall[cur.x][cur.y][next.x][next.y];
53if( w == 0 ) continue;//
是牆54
if( w > 0 && (cur.key/bin[w]%2 == 0)) continue;//
是門沒鑰匙
55 next.step = cur.step+1
;56 next.key = cur.key |key[next.x][next.y];
57if( dp[next.key][next.x][next.y]< 0)58
62else
if(dp[next.key][next.x][next.y] >next.step)
6367}68
}69if( res ==int_max )
7074 printf("
%d\n
", res);75}
76int main(int argc, char *ar**)
7791 scanf("
%d", &tmp);
92for( int i = 0 ; i < tmp ; i++)
9397
solve();98}
99 }
hdu5094Maze bfs 狀態壓縮
開乙個四維陣列記錄牆和門的情況 開乙個三維陣列標記在該位置時有哪些鑰匙 鑰匙的記錄用狀態壓縮 注意在同乙個位置可以有多把鑰匙,在這卡了乙個晚上。include include include include using namespace std const int maxn 60 int vis ...
hdu5094 狀態壓縮dp dps
題目大意 給定乙個棋盤,要求從 1,1 走到 n,m 相鄰格仔之前可能是牆,門或者什麼都沒有,牆的話就無法通過,門的話就必須有對應的鑰匙才能通過,要求求出最少的步數,若無法到達就輸出1。除錯了近兩個小時,一直找不到錯在哪,後來看了別人的程式,發現忘記考慮1 1的棋盤了。真是嗶了狗了。題很簡單,就是對...
hdu1074狀態壓縮
很明顯的狀態壓縮題目。當然了如果他的意識只有是求最小值沒有要求輸出那個輸出的順序,那麼直接用揹包,甚至是貪心都是可以做出來的,但是要求順序這個揹包的話沒有辦法吧資料記錄下來。所以用二進位制壓縮。所謂的二進位制壓縮就是用二進位制來表示事情的完成程度和狀況,比如1,就是0000001表示第乙個作業做了,...