#贪心
### 补充题目
- 对于 $1\times 2$ 的瓷砖,你不可以竖着放(即 $2\times 1$ 的形式);
- 有可能全部铺 $1\times 1$ 的瓷砖会更优。
### 思路
看到不可以竖着放,我们会很自然地使用贪心。
对于每一行,我们都单独处理。每两个相邻的字符 `.`,我们都可以使用 $1\times 2$ 或者是 $1\times 1$ 的瓷砖来填充,取 $\min$ 值即可。如果只剩下了一个 `.`,我们就使用 $1\times 1$ 的瓷砖。
### 贪心正确性判断
- 对于偶数个连续的 `.`,我们可以全部分成一节节的两个字符的组合,取 $\min$ 值;
- 对于奇数个连续的 `.`,我们可以拆分成偶数个连续的 `.` 加上一个 `.`($1\times 1$)。
因此这个贪心完全正确。
### 代码
```cpp
#include <iostream>
#include <cstring>
using namespace std;
int t, n, m, x, y, ans;
string s;
int main() {
for (cin >> t; t; --t) {
cin >> n >> m >> x >> y, ans = 0;
for (int i = 1; i <= n; ++i) { // 将矩阵分行处理
cin >> s, s += ' '; // 尾随空格,防止当i=m-1的时候i+1越界
for (int i = 0; i < s.size(); ++i) {
bool o = s[i] == '.' && s[i + 1] == '.'; // 判断是否能铺1*2的瓷砖
if (o) { // 如果可以
s[i] = s[i + 1] = '*' /*不管怎么样,最后都会被铺满*/,
ans += min(2 * x, y); // 只需取1*1和1*2的最小值
} else if (s[i] == '.') {
s[i] = '*', ans += x; // 不行的话就直接铺1*1的瓷砖
}
}
}
cout << ans << '\n';
}
return 0;
}
```