fork download
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6. typedef pair<int, int> ii;
  7.  
  8. const int INF = 1e9;
  9. const ll LINF = 1e18;
  10.  
  11. template<typename T>
  12. void minimize(T& a, const T& b) {
  13. if (b < a) a = b;
  14. }
  15.  
  16. int n, m;
  17. string s;
  18. int adj[20][20]; // adj[c1][c2] = Số vị trí mà hai chữ cái c1 và c2 nằm kề nhau trong xâu s
  19. int dp[1 << 20]; // dp[mask] = Độ trễ tối thiểu có thể có khi đặt các chữ cái trong mask
  20. // vào các vị trí từ 0 đến popcount(mask) - 1 trên bàn phím
  21.  
  22. int main() {
  23. ios::sync_with_stdio(false);
  24. cin.tie(nullptr);
  25. cin >> n >> m;
  26. cin >> s;
  27.  
  28. for (int i = 0; i + 1 < n; i++) {
  29. int c1 = s[i] - 'a', c2 = s[i + 1] - 'a';
  30. adj[c1][c2]++;
  31. adj[c2][c1]++;
  32. }
  33.  
  34. for (int mask = 0; mask < (1 << m); mask++) {
  35. if (mask == 0) {
  36. dp[mask] = 0;
  37. continue;
  38. }
  39. dp[mask] = INF;
  40. int pos = __builtin_popcount(mask) - 1;
  41. for (int c = 0; c < m; c++) { // Chữ cái được đặt vào vị trí pos
  42. if (!(mask & (1 << c))) continue;
  43. int prev_mask = mask ^ (1 << c);
  44. int delta = 0;
  45. for (int c1 = 0; c1 < m; c1++) {
  46. if (c1 == c) continue;
  47. if ((prev_mask >> c1) & 1) {
  48. delta += adj[c][c1] * pos;
  49. }
  50. else {
  51. delta -= adj[c][c1] * pos;
  52. }
  53. }
  54. minimize(dp[mask], dp[prev_mask] + delta);
  55. }
  56. }
  57.  
  58. cout << dp[(1 << m) - 1] << '\n';
  59. }
  60.  
Success #stdin #stdout 0s 5316KB
stdin
6 3
aacabc
stdout
5