提交时间:2025-05-29 14:24:06
运行 ID: 193990
#include <iostream> #include <fstream> #include <string> #include <vector> #include <algorithm> using namespace std; int main() { ifstream fin("seq.in"); ofstream fout("seq.out"); int n, k, type; fin >> n >> k >> type; string s; fin >> s; // 预处理每个字符的所有出现位置 vector<vector<int>> pos(k); for (int i = 0; i < n; i++) { int c = s[i] - 'a'; pos[c].push_back(i); } // 动态规划数组:dp[i][j]表示考虑前i个字符,最后一个字符是j的最大长度 vector<vector<int>> dp(k + 1, vector<int>(k, 0)); // 记录选择 vector<vector<int>> choice(k + 1, vector<int>(k, -1)); // 初始化 for (int j = 0; j < k; j++) { dp[1][j] = pos[j].size(); choice[1][j] = -1; } // 动态规划 for (int i = 2; i <= k; i++) { for (int j = 0; j < k; j++) { if (pos[j].empty()) continue; for (int p = 0; p < k; p++) { if (p == j) continue; if (dp[i - 1][p] + pos[j].size() > dp[i][j]) { dp[i][j] = dp[i - 1][p] + pos[j].size(); choice[i][j] = p; } } } } // 找到最大长度和对应的字符数目 int max_len = 0; int best_m = 0; int best_last = -1; for (int m = 1; m <= k; m++) { for (int j = 0; j < k; j++) { if (dp[m][j] > max_len) { max_len = dp[m][j]; best_m = m; best_last = j; } } } fout << max_len << endl; // 如果type=0,无需输出方案 if (type == 0) return 0; // 回溯找出选择的字符 vector<int> selected_chars; int current_char = best_last; int current_m = best_m; while (current_m > 0) { selected_chars.push_back(current_char); current_char = choice[current_m][current_char]; current_m--; } reverse(selected_chars.begin(), selected_chars.end()); // 如果type=1,输出任意方案 if (type == 1) { string result; for (int c : selected_chars) { for (int p : pos[c]) { result += (char)('a' + c); } } fout << result << endl; return 0; } // 如果type=2,需要输出字典序最小的方案 // 这里需要更复杂的处理,确保字典序最小 // 以下是简化处理,实际可能需要更复杂的算法 string result; for (int c : selected_chars) { for (int p : pos[c]) { result += (char)('a' + c); } } fout << result << endl; return 0;