bzoj 1295 1295: [SCOI2009]最长距离
思路:对于每个点出发bfs做一次dp, dp[ i ][ j ][ k ] 表示从枚举的该点能不能经过k个障碍物到达(i , j)。
1 #include<bits/stdc++.h> 2 #define LL long long 3 #define ll long long 4 #define fi first 5 #define se second 6 #define mk make_pair 7 #define pii pair<int,int> 8 #define piii pair<int, pair<int,int> > 9 10 using namespace std; 11 12 const int N = 30; 13 const int inf = 0x3f3f3f3f; 14 const LL INF = 0x3f3f3f3f3f3f3f3f; 15 const int mod = 1e9 + 7; 16 const int Mod = 2009; 17 18 int dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0}; 19 bool dp[N][N][31]; 20 int s[N][N]; 21 int n, m, t; 22 23 bool check(int x, int y) { 24 if(x < 0 || x >= n) return false; 25 if(y < 0 || y >= m) return false; 26 return true; 27 } 28 29 void bfs(int sx, int sy) { 30 queue<piii> que; 31 if(s[sx][sy]) { 32 que.push(mk(1, mk(sx, sy))); 33 dp[sx][sy][1] = true; 34 } else { 35 que.push(mk(0, mk(sx, sy))); 36 dp[sx][sy][0] = true; 37 } 38 39 while(!que.empty()) { 40 piii u = que.front(); que.pop(); 41 int x = u.se.fi, y = u.se.se, w = u.fi; 42 for(int i = 0; i < 4; i++) { 43 int nx_x = x + dx[i], nx_y = y + dy[i]; 44 if(check(nx_x, nx_y)) { 45 int nx_w = w + s[nx_x][nx_y]; 46 if(nx_w <= t && !dp[nx_x][nx_y][nx_w]) { 47 que.push(mk(nx_w, mk(nx_x, nx_y))); 48 dp[nx_x][nx_y][nx_w] = true; 49 } 50 } 51 } 52 } 53 } 54 int main() { 55 scanf("%d%d%d", &n, &m, &t); 56 for(int i = 0; i < n; i++) 57 for(int j = 0; j < m; j++) 58 scanf("%1d", &s[i][j]); 59 60 int ans = 0; 61 for(int i = 0; i < n; i++) { 62 for(int j = 0; j < m; j++) { 63 memset(dp, false, sizeof(dp)); 64 bfs(i, j); 65 for(int u = 0; u < n; u++) { 66 for(int v = 0; v < m; v++) { 67 for(int k = 0; k <= t; k++) { 68 if(dp[u][v][k]) { 69 ans = max(ans, (i - u) * (i - u) + (j - v) * (j - v)); 70 break; 71 } 72 } 73 } 74 } 75 } 76 } 77 78 printf("%.6f\n", sqrt(ans)); 79 return 0; 80 } 81 82 /* 83 */