Advertisement
vlatkovski

Fotografija (olimpijada 2013) but it's wrong

Nov 12th, 2018
432
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.93 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. #define endl '\n'
  4. #define all(v) begin(v), end(v)
  5. typedef long long ll;
  6. typedef long double ld;
  7. typedef std::pair<int, int> ii;
  8. typedef std::vector<ii> vii;
  9. typedef std::vector<int> vi;
  10.  
  11.  
  12.  
  13.  
  14. int N, M;
  15. int V[102], P[16];
  16. int numempty;
  17. vector<int> emptypos;
  18.  
  19. vector<int> dp[3][15][15];
  20. vector<int> nxt[3][15][15];
  21.  
  22. inline bool isbad(int a, int b, int c) {
  23.   return ((a < b && b > c) || (a > b && b < c));
  24. }
  25.  
  26. int F(int available, int prevstatus, int prevplacedidx, int numdone) {
  27.   if (numdone == numempty) return 0;
  28.   int &state = dp[prevstatus][prevplacedidx][numdone][available];
  29.   if (state != -1) return state;
  30.  
  31.   int &statepath = nxt[prevstatus][prevplacedidx][numdone][available];
  32.   state = 1e6;
  33.   int currpos = emptypos[numdone];
  34.   int prevplacedpos = numdone > 0 ? emptypos[numdone-1] : -1;
  35.   int prevplacedheight = numdone > 0 ? P[prevplacedidx] : -1;
  36.   int nextplacingpos = numdone+1 < numempty ? emptypos[numdone+1] : -1;
  37.  
  38.   for (int currheightidx = 0; currheightidx < M; ++currheightidx) {
  39.     if (!(available & (1 << currheightidx))) continue;
  40.     int height = P[currheightidx];
  41.     int bad, status;
  42.     if (prevplacedpos == -1 || prevplacedpos + 2 < currpos) {
  43.       bad = currpos >= 2 && isbad(V[currpos-2], V[currpos-1], height);
  44.       if (currpos+1 < N && (nextplacingpos == -1 || currpos + 1 < nextplacingpos)) {
  45.         bad += isbad(V[currpos-1], height, V[currpos+1]);
  46.       }
  47.       status = height == V[currpos-1] ? 0 : (height < V[currpos-1] ? 1 : 2);
  48.     } else if (prevplacedpos + 2 == currpos) {
  49.       bad = currpos >= 2 && isbad(prevplacedheight, V[currpos-1], height);
  50.       if (currpos+1 < N && (nextplacingpos == -1 || currpos + 1 < nextplacingpos)) {
  51.         bad += isbad(V[currpos-1], height, V[currpos+1]);
  52.       }
  53.       status = height == V[currpos-1] ? 0 : (height < V[currpos-1] ? 1 : 2);
  54.     } else if (prevplacedpos + 1 == currpos) {
  55.       int prevprevheight = prevstatus == 0 ? prevplacedheight : (prevstatus == 1 ? prevplacedheight+1 : prevplacedheight-1);
  56.       bad = currpos >= 2 && isbad(prevprevheight, prevplacedheight, height);
  57.       if (currpos+1 < N && (nextplacingpos == -1 || currpos + 1 < nextplacingpos)) {
  58.         bad += isbad(prevplacedheight, height, V[currpos+1]);
  59.       }
  60.       status = height == prevplacedheight ? 0 : (height < prevplacedheight ? 1 : 2);
  61.     } else {
  62.       continue;
  63.     }
  64.     if (currpos+2 < N && (nextplacingpos == -1 || currpos + 2 < nextplacingpos)) {
  65.       bad += isbad(height, V[currpos+1], V[currpos+2]);
  66.     }
  67.     int result = bad + F(available & ~(1 << currheightidx), status, currheightidx, numdone+1);
  68.     if (result < state) {
  69.       statepath = currheightidx;
  70.       state = result;
  71.     }
  72.   }
  73.   return state;
  74. }
  75.  
  76. void Solve() {
  77.   cin >> N;
  78.   for (int i = 0; i < N; ++i) {
  79.     cin >> V[i];
  80.     if (V[i] == 0) {
  81.       emptypos.push_back(i);
  82.     }
  83.   }
  84.   cin >> M;
  85.   for (int i = 0; i < M; ++i) {
  86.     cin >> P[i];
  87.   }
  88.   sort(P, P+M, [&](int a, int b) {
  89.     string sa = to_string(a), sb = to_string(b);
  90.     return lexicographical_compare(sa.begin(), sa.end(), sb.begin(), sb.end());
  91.   });
  92.   numempty = emptypos.size();
  93.   for (int prevstatus = 0; prevstatus < 3; ++prevstatus) {
  94.     for (int prevplacedidx = 0; prevplacedidx < 15; ++prevplacedidx) {
  95.       for (int numdone = 0; numdone < 15; ++numdone) {
  96.         dp[prevstatus][prevplacedidx][numdone].assign(1<<M, -1);
  97.         nxt[prevstatus][prevplacedidx][numdone].resize(1<<M);
  98.       }
  99.     }
  100.   }
  101.  
  102.   int available = (1 << M) - 1, prevstatus = 0, prevplacedidx = 0, numdone = 0;
  103.   int ans = F(available, prevstatus, prevplacedidx, numdone);
  104.  
  105.   vi placed(numempty);
  106.   while (numdone < numempty) {
  107.     int currpos = emptypos[numdone];
  108.     int prevplacedpos = numdone > 0 ? emptypos[numdone-1] : -1;
  109.     int prevplacedheight = numdone > 0 ? P[prevplacedidx] : -1;
  110.     int currheightidx = nxt[prevstatus][prevplacedidx][numdone][available];
  111.     int height = P[currheightidx];
  112.     placed[numdone] = height;
  113.     int status;
  114.     if (prevplacedpos == -1 || prevplacedpos + 2 < currpos) {
  115.       status = height == V[currpos-1] ? 0 : (height < V[currpos-1] ? 1 : 2);
  116.     } else if (prevplacedpos + 2 == currpos) {
  117.       status = height == V[currpos-1] ? 0 : (height < V[currpos-1] ? 1 : 2);
  118.     } else if (prevplacedpos + 1 == currpos) {
  119.       status = height == prevplacedheight ? 0 : (height < prevplacedheight ? 1 : 2);
  120.     }
  121.     available &= ~(1 << currheightidx);
  122.     prevstatus = status;
  123.     prevplacedidx = currheightidx;
  124.     numdone = numdone + 1;
  125.   }
  126.  
  127. //  cout << ans << endl;
  128.   int j = 0;
  129.   for (int i = 0; i < N; ++i) {
  130.     if (V[i] == 0) {
  131.       cout << placed[j] << " ";
  132.       ++j;
  133.     } else {
  134.       cout << V[i] << " ";
  135.     }
  136.   }
  137. }
  138.  
  139. int main() {
  140.   std::ios::sync_with_stdio(false);
  141.   std::cin.tie(nullptr);
  142.   #ifdef _DEBUG
  143.   std::freopen("in.txt", "r", stdin);
  144.   std::freopen("out.txt", "w", stdout);
  145.   #endif
  146.   Solve();
  147. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement