#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秒后给出正解
方法思路
- 状态生成:生成所有可能的行状态,每个状态是一个满足相邻字符不同的字符序列。
- 转移矩阵:预处理所有可能的状态转移,确保相邻列的状态在每一行上的字符都不同。
- 动态规划:使用动态规划来计算从第一列到最后一列的最小修改次数,维护每个状态的最小修改次数,并利用预处理的状态转移来更新当前状态的最小值。