#include <bits/stdc++.h>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<string> mat(n);
for (int i = 0; i < n; ++i) {
cin >> mat[i];
}
// 将输入转换为数值矩阵,并转置为按列存储
vector<vector<int>> cols(m, vector<int>(n));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
char c = mat[i][j];
if (c == 'r') cols[j][i] = 0;
else if (c == 'e') cols[j][i] = 1;
else cols[j][i] = 2;
}
}
// 生成所有可能的状态
vector<vector<int>> all_states;
function<void(int, vector<int>&)> dfs = [&](int row, vector<int>& current) {
if (row == n) {
all_states.push_back(current);
return;
}
for (int c = 0; c < 3; ++c) {
if (!current.empty() && current.back() == c) continue;
current.push_back(c);
dfs(row + 1, current);
current.pop_back();
}
};
vector<int> tmp;
dfs(0, tmp);
int num_states = all_states.size();
// 预处理状态转移矩阵
vector<vector<bool>> transition(num_states, vector<bool>(num_states, false));
for (int p = 0; p < num_states; ++p) {
for (int q = 0; q < num_states; ++q) {
bool valid = true;
for (int i = 0; i < n; ++i) {
if (all_states[p][i] == all_states[q][i]) {
valid = false;
break;
}
}
transition[p][q] = valid;
}
}
// 预处理每个状态在各列的修改成本
vector<vector<int>> cost(m, vector<int>(num_states));
for (int j = 0; j < m; ++j) {
for (int s = 0; s < num_states; ++s) {
int cnt = 0;
for (int i = 0; i < n; ++i) {
if (all_states[s][i] != cols[j][i]) {
cnt++;
}
}
cost[j][s] = cnt;
}
}
// 动态规划
vector<int> prev_dp(num_states, INT_MAX);
for (int s = 0; s < num_states; ++s) {
prev_dp[s] = cost[0][s];
}
for (int j = 1; j < m; ++j) {
vector<int> current_dp(num_states, INT_MAX);
for (int prev_s = 0; prev_s < num_states; ++prev_s) {
if (prev_dp[prev_s] == INT_MAX) continue;
for (int curr_s = 0; curr_s < num_states; ++curr_s) {
if (transition[prev_s][curr_s]) {
if (prev_dp[prev_s] + cost[j][curr_s] < current_dp[curr_s]) {
current_dp[curr_s] = prev_dp[prev_s] + cost[j][curr_s];
}
}
}
}
prev_dp = move(current_dp);
}
int ans = *min_element(prev_dp.begin(), prev_dp.end());
cout << ans << endl;
return 0;
}
deepseek思考600秒后给出正解
方法思路
- 状态生成:生成所有可能的行状态,每个状态是一个满足相邻字符不同的字符序列。
- 转移矩阵:预处理所有可能的状态转移,确保相邻列的状态在每一行上的字符都不同。
- 动态规划:使用动态规划来计算从第一列到最后一列的最小修改次数,维护每个状态的最小修改次数,并利用预处理的状态转移来更新当前状态的最小值。

京公网安备 11010502036488号