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. const int N = 1e2 + 5;
  17.  
  18. int prime[17] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59};
  19.  
  20. int n;
  21. int a[N];
  22.  
  23. int prime_mask[60]; // prime_mask[x] = mask đại diện cho tập hợp các ước nguyên tố của x
  24. int dp[N][1 << 17]; // dp[i][mask] = Tổng bé nhất đạt được khi xét đến vị trí thứ i
  25. // với mask đại diện cho tập hợp các ước nguyên tố đã xuất hiện
  26. int b[N];
  27.  
  28. int main() {
  29. ios::sync_with_stdio(false);
  30. cin.tie(nullptr);
  31. cin >> n;
  32. for (int i = 1; i <= n; i++) cin >> a[i];
  33.  
  34. for (int x = 1; x <= 59; x++) {
  35. for (int i = 0; i < 17; i++) {
  36. if (x % prime[i] == 0) prime_mask[x] |= (1 << i);
  37. }
  38. }
  39.  
  40. for (int i = 0; i <= n; i++) {
  41. for (int mask = 0; mask < (1 << 17); mask++) {
  42. dp[i][mask] = INF;
  43. }
  44. }
  45. dp[0][0] = 0;
  46.  
  47. for (int i = 0; i < n; i++) {
  48. for (int mask = 0; mask < (1 << 17); mask++) {
  49. if (dp[i][mask] == INF) continue;
  50. for (int x = 1; x <= 59; x++) {
  51. if ((prime_mask[x] & mask) == 0) {
  52. int next_mask = mask | prime_mask[x];
  53. minimize(dp[i + 1][next_mask], dp[i][mask] + abs(x - a[i + 1]));
  54. }
  55. }
  56. }
  57. }
  58.  
  59. int best_mask = 0;
  60. for (int mask = 0; mask < (1 << 17); mask++) {
  61. if (dp[n][mask] < dp[n][best_mask]) best_mask = mask;
  62. }
  63.  
  64. for (int i = n; i >= 1; i--) {
  65. for (int x = 1; x <= 59; x++) {
  66. if ((best_mask & prime_mask[x]) == prime_mask[x]) {
  67. int prev_mask = best_mask ^ prime_mask[x];
  68. if (dp[i - 1][prev_mask] + abs(x - a[i]) == dp[i][best_mask]) {
  69. b[i] = x;
  70. best_mask = prev_mask;
  71. break;
  72. }
  73. }
  74. }
  75. }
  76.  
  77. for (int i = 1; i <= n; i++) cout << b[i] << ' ';
  78. }
  79.  
Success #stdin #stdout 0.01s 8028KB
stdin
5
1 6 4 2 8
stdout
1 5 3 1 8