Advertisement
erek1e

Knife - BIO 2023 Round 2

Apr 11th, 2023
528
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.71 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. int main() {
  6.     freopen("input.txt", "r", stdin);
  7.     freopen("output.txt", "w", stdout);
  8.     ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
  9.     int n, m; cin >> n >> m;
  10.     vector<int> s(2*n);
  11.     for (int &x : s) cin >> x;
  12.  
  13.     vector<int> lastOccurance(1+m, -1); // x position of rightmost occurance
  14.     for (int i = 0; i < n; ++i) {
  15.         lastOccurance[s[i]] = i;
  16.         lastOccurance[s[n+i]] = i;
  17.     }
  18.  
  19.     vector<int> lopresum(1+n);
  20.     for (int i = 1; i <= m; ++i) if (lastOccurance[i] >= 0) lopresum[lastOccurance[i]+1]++;
  21.     for (int i = 1; i <= n; ++i) lopresum[i] += lopresum[i-1];
  22.  
  23.     vector<pair<int, int>> componentFinish(2*n); // position, 0/1/2
  24.     for (int i = n-1; i >= 0; --i) {
  25.         if (i < n-1 && s[i] == s[i+1]) componentFinish[i] = componentFinish[i+1];
  26.         else componentFinish[i] = {i, 0};
  27.         if (i < n-1 && s[n+i] == s[n+i+1]) componentFinish[n+i] = componentFinish[n+i+1];
  28.         else componentFinish[n+i] = {i, 1};
  29.  
  30.         if (s[i] == s[n+i]) {
  31.             if (componentFinish[i].first > i || componentFinish[n+i].first > i) {
  32.                 componentFinish[i] = componentFinish[n+i] = max(componentFinish[i], componentFinish[n+i]);
  33.             } else componentFinish[i] = componentFinish[n+i] = {i, 2};
  34.         }
  35.     }
  36.  
  37.  
  38.     // dp on distance travelled right and which of the last column's two cells are occupied
  39.     //  value in dp is time to finish if filled in all gaps of values that do not appear further to the right
  40.     vector<int> dp[3]{}; // 0 means top, 1 means bottom, 2 means both
  41.     dp[0].resize(n), dp[1].resize(n), dp[2].resize(n);
  42.     for (int i = n-2; i >= 0; --i) {
  43.         for (int type = 2; type >= 0; --type) {
  44.             pair<int, int> choice[2]{}; int v[2]{};
  45.             if (type == 0) {
  46.                 choice[0] = componentFinish[i+1]; v[0] = s[i+1];
  47.                 choice[1] = componentFinish[n+i]; v[1] = s[n+i];
  48.                 if (choice[1].first == i) choice[1].second = 2;
  49.             } else if (type == 1) {
  50.                 choice[0] = componentFinish[i]; v[0] = s[i];
  51.                 if (choice[0].first == i) choice[0].second = 2;
  52.                 choice[1] = componentFinish[n+i+1]; v[1] = s[n+i+1];
  53.             } else {
  54.                 choice[0] = componentFinish[i+1]; v[0] = s[i+1];
  55.                 choice[1] = componentFinish[n+i+1]; v[1] = s[n+i+1];
  56.             }
  57.             // if not last occurance, add one to cost
  58.             int cost[2]{};
  59.             for (int ch = 0; ch <= 1; ++ch) {
  60.                 if (lastOccurance[v[ch]] != choice[ch].first) ++cost[ch];
  61.                 cost[ch] += dp[choice[ch].second][choice[ch].first];
  62.                 int extra = lopresum[choice[ch].first + 1] - lopresum[i + 1];
  63.                 cost[ch] += extra;
  64.             }
  65.             dp[type][i] = min(cost[0], cost[1]);
  66.         }
  67.     }
  68.  
  69.     int extra = lopresum[componentFinish[0].first + 1];
  70.     if (lastOccurance[s[0]] == componentFinish[0].first) --extra;
  71.     cout << dp[componentFinish[0].second][componentFinish[0].first] + extra << endl;
  72.     return 0;
  73. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement