作为一道提高T2难度的题目,它成功的让我自闭了。。。
读完题第一感觉:flood_fill,第二感觉:第二问不可做。。。
于是思考许久,还是翻开了题解,然后看到一句:“每个蓄水厂覆盖的区间必然连续,否则输出0”。
题目有变的可做起来,于是瞎搞了一波flood_fill + 区间DP。
结果只有80分。。。一个点TLE,一个点WA。。。
TLE好办,对第一行来波记忆化就完了,WA就难办了,下了个数据点发现,还要特判n==1的情况。
终于AC辣!!!!
AC 代码:
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <queue> inline int min(const int a, const int b) { return a > b ? b : a; } inline int max(const int a, const int b) { return a < b ? b : a; } inline void read(int & x) { x = 0; int k = 1; char c = getchar(); while (!isdigit(c)) if (c == '-') c = getchar(), k = -1; else c = getchar(); while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48), c = getchar(); x *= k; } struct node { int x, y; }fir, cur; int n, m, nx, ny, out; int h[505][505]; int v[505][505]; int dk[505]; int dp[505][505]; int mem[505][505]; int l[505], r[505], ans[505]; int brd[505]; int dx[] = {0, 0, 1, -1}; int dy[] = {1, -1, 0, 0}; void bfs(int x, int now) { if (dk[now]) { l[now] = l[dk[now]], r[now] = r[dk[now]], ans[now] = ans[dk[now]]; return; } std::queue <node> Q; fir.x = x, fir.y = now; Q.push(fir); v[x][now] = 1; while (!Q.empty()) { cur = Q.front(); Q.pop(); for (int i = 0; i < 4; ++i) { nx = cur.x + dx[i], ny = cur.y + dy[i]; if (v[nx][ny] || nx < 1 || nx > n || ny > m || ny < 1 || h[nx][ny] >= h[cur.x][cur.y]) continue; fir.x = nx, fir.y = ny; if (nx == 1) dk[ny] = now; v[nx][ny] = 1; Q.push(fir); if (nx == n) l[now] = min(l[now], ny), r[now] = max(r[now], ny), ++ans[now], mem[n][ny] = 1; } } } void flood_fill(int now) { memset(v, false, sizeof(v)); bfs(1, now); for (int i = l[now]; i <= r[now]; ++i) brd[i] = 1; if (l[now] <= r[now]) for (int i = l[now]; i <= r[now]; ++i) for (int j = i; j <= r[now]; ++j) dp[i][j] = 1; } inline void dp_it() { for (int len = 1; len <= m; ++len) for (int i = 1, j = i + len - 1; j <= m; ++i, j = i + len - 1) for (int k = i; k < j; ++k) dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j]); } int main() { memset(l, 0x3f, sizeof(l)); memset(dp, 0x3f, sizeof(dp)); read(n), read(m); bool flag = true; for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) read(h[i][j]); for (int i = 1; i <= m; ++i) flood_fill(i); for (int i = 1; i <= m; ++i) if (!mem[n][i]) ++out; if (out != 0) { if (n == 1) printf("1\n%d", out); else printf("0\n%d", out); return 0; } dp_it(); printf("1\n%d", dp[1][m]); return 0; }