T1 [JZOJ3503] 粉刷
题目描述
鸡腿想到了一个很高(sha)明(bi)的问题,墙可以看作一个 $N \times M$ 的矩阵,有一些格子是有污点的。现在鸡腿可以竖着刷一次,覆盖连续的最多 $C$ 列,或者横着刷一次,覆盖连续的最多R行。现在鸡腿把墙上的情况告诉你,请你告诉鸡腿最少要刷多少次才能刷干净!
数据范围
对于 $50\%$ 的数据,$1 \leq N,M \leq 5$
对于 $100\%$ 的数据,$1 \leq N,M,R,C \leq 15$
分析
临时换题什么鬼啊 还有本题正解暴力??
枚举横着刷的所有情况,然后对于每种情况竖着刷完剩下的点
//结束前十分钟开始打 写得不是很好看 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> using namespace std; #define ll long long #define inf 0x3f3f3f3f #define N 16 int n, m, r, c, ans = inf; int sum[N], line[N]; char g[N][N]; void dfs(int x, int t, int last) { if (last) { int now = t; for (int i = 1; i <= m; i++) if (sum[i]) i += c - 1, now++; ans = min(ans, now); } if (x > n) return; dfs(x + 1, t, 0); for (int i = x; i <= x + r - 1 && i <= n; i++) for (int j = 1; j <= m; j++) if (g[i][j] == 'X') sum[j]--; dfs(x + c, t + 1, 1); for (int i = x; i <= x + r - 1 && i <= n; i++) for (int j = 1; j <= m; j++) if (g[i][j] == 'X') sum[j]++; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { scanf(" %c", &g[i][j]); if (g[i][j] == 'X') sum[j]++, line[i]++; } scanf("%d%d", &r, &c); dfs(1, 0, 1); printf("%d\n", ans); return 0; }