1. 程式人生 > >Robbery【記憶化搜尋】

Robbery【記憶化搜尋】

題意:
在一個w * h的圖上,t個時刻,然後給你一些資訊,知道某些時刻沒有小偷的矩陣,問哪些時刻可以唯一確定小偷所在的位置,和確定小偷是否已經逃走,如果沒逃走,但是也沒有時刻可以可以確定小偷位置,輸出不知道

解法:記憶化搜尋
dp[i][j][t]=1 表示t時刻ij可能出現劫犯
dp[i][j][t]=0 表示t時刻ij不可能出現劫犯

程式碼:

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue> #include <math.h> #include <map> #include <string> #include <vector> using namespace std; int dir[][2] = { {0,0},{1,0},{-1,0},{0,1}, {0,-1} }; int W, H, T; bool is_ok(int x, int y) { if (x >= 1 && x <= W && y >= 1 && y <= H) return
true; return false; } int n; int dp[110][110][110]; //dp[i][j][t]=1 表示t時刻ij可能出現劫犯 //dp[i][j][t]=0 表示t時刻ij不可能出現劫犯 vector<pair<int, int> > ans[110]; int dfs(int x, int y, int t) { if (dp[x][y][t] != -1) return dp[x][y][t]; if (t == T) { dp[x][y][t] = 1
; return 1; } dp[x][y][t] = 0; for (int i = 0; i < 5; i++) { int xx = x + dir[i][0]; int yy = y + dir[i][1]; if (!is_ok(xx, yy)) continue; if (dfs(xx, yy, t + 1)) dp[x][y][t] = 1; } return dp[x][y][t]; } int main() { int cases = 1; while (~scanf("%d%d%d", &W, &H, &T) && W) { memset(dp, -1, sizeof(dp)); for (int i = 0; i <= 105;i++) ans[i].clear(); scanf("%d",&n); int t, x, xx, y, yy; for (int ii = 1; ii <= n; ii++) { scanf("%d%d%d%d%d", &t, &x, &y, &xx, &yy); for (int i = x; i <= xx; i++) for (int j = y; j <= yy; j++) dp[i][j][t] = 0; } for (int i = 1; i <= W; i++) for (int j = 1; j <= H; j++) dfs(i, j, 1); printf("Robbery #%d:\n", cases++); int ok; int res = 1; for (int k = 1; k <= T; k++) { ok = 0; for (int i = 1; i <= W; i++) { for (int j = 1; j <= H; j++) { if (dp[i][j][k] == 1) { ans[k].push_back((make_pair(i, j))); ok = 1; } } } if (!ok) { res = 0; break; } } if (!res) { puts("The robber has escaped."); printf("\n"); continue; } for (int i = 1; i <= T; i++) { if (ans[i].size() == 1) { printf("Time step %d: The robber has been at %d,%d.\n",i,ans[i][0].first,ans[i][0].second); res = 0; } } if (res) puts("Nothing known."); printf("\n"); } return 0; }