Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- #define endl '\n'
- #define all(v) begin(v), end(v)
- typedef long long ll;
- typedef long double ld;
- typedef std::pair<int, int> ii;
- typedef std::vector<ii> vii;
- typedef std::vector<int> vi;
- int N, M;
- int V[102], P[16];
- int numempty;
- vector<int> emptypos;
- vector<int> dp[3][15][15];
- vector<int> nxt[3][15][15];
- inline bool isbad(int a, int b, int c) {
- return ((a < b && b > c) || (a > b && b < c));
- }
- int F(int available, int prevstatus, int prevplacedidx, int numdone) {
- if (numdone == numempty) return 0;
- int &state = dp[prevstatus][prevplacedidx][numdone][available];
- if (state != -1) return state;
- int &statepath = nxt[prevstatus][prevplacedidx][numdone][available];
- state = 1e6;
- int currpos = emptypos[numdone];
- int prevplacedpos = numdone > 0 ? emptypos[numdone-1] : -1;
- int prevplacedheight = numdone > 0 ? P[prevplacedidx] : -1;
- int nextplacingpos = numdone+1 < numempty ? emptypos[numdone+1] : -1;
- for (int currheightidx = 0; currheightidx < M; ++currheightidx) {
- if (!(available & (1 << currheightidx))) continue;
- int height = P[currheightidx];
- int bad, status;
- if (prevplacedpos == -1 || prevplacedpos + 2 < currpos) {
- bad = currpos >= 2 && isbad(V[currpos-2], V[currpos-1], height);
- if (currpos+1 < N && (nextplacingpos == -1 || currpos + 1 < nextplacingpos)) {
- bad += isbad(V[currpos-1], height, V[currpos+1]);
- }
- status = height == V[currpos-1] ? 0 : (height < V[currpos-1] ? 1 : 2);
- } else if (prevplacedpos + 2 == currpos) {
- bad = currpos >= 2 && isbad(prevplacedheight, V[currpos-1], height);
- if (currpos+1 < N && (nextplacingpos == -1 || currpos + 1 < nextplacingpos)) {
- bad += isbad(V[currpos-1], height, V[currpos+1]);
- }
- status = height == V[currpos-1] ? 0 : (height < V[currpos-1] ? 1 : 2);
- } else if (prevplacedpos + 1 == currpos) {
- int prevprevheight = prevstatus == 0 ? prevplacedheight : (prevstatus == 1 ? prevplacedheight+1 : prevplacedheight-1);
- bad = currpos >= 2 && isbad(prevprevheight, prevplacedheight, height);
- if (currpos+1 < N && (nextplacingpos == -1 || currpos + 1 < nextplacingpos)) {
- bad += isbad(prevplacedheight, height, V[currpos+1]);
- }
- status = height == prevplacedheight ? 0 : (height < prevplacedheight ? 1 : 2);
- } else {
- continue;
- }
- if (currpos+2 < N && (nextplacingpos == -1 || currpos + 2 < nextplacingpos)) {
- bad += isbad(height, V[currpos+1], V[currpos+2]);
- }
- int result = bad + F(available & ~(1 << currheightidx), status, currheightidx, numdone+1);
- if (result < state) {
- statepath = currheightidx;
- state = result;
- }
- }
- return state;
- }
- void Solve() {
- cin >> N;
- for (int i = 0; i < N; ++i) {
- cin >> V[i];
- if (V[i] == 0) {
- emptypos.push_back(i);
- }
- }
- cin >> M;
- for (int i = 0; i < M; ++i) {
- cin >> P[i];
- }
- sort(P, P+M, [&](int a, int b) {
- string sa = to_string(a), sb = to_string(b);
- return lexicographical_compare(sa.begin(), sa.end(), sb.begin(), sb.end());
- });
- numempty = emptypos.size();
- for (int prevstatus = 0; prevstatus < 3; ++prevstatus) {
- for (int prevplacedidx = 0; prevplacedidx < 15; ++prevplacedidx) {
- for (int numdone = 0; numdone < 15; ++numdone) {
- dp[prevstatus][prevplacedidx][numdone].assign(1<<M, -1);
- nxt[prevstatus][prevplacedidx][numdone].resize(1<<M);
- }
- }
- }
- int available = (1 << M) - 1, prevstatus = 0, prevplacedidx = 0, numdone = 0;
- int ans = F(available, prevstatus, prevplacedidx, numdone);
- vi placed(numempty);
- while (numdone < numempty) {
- int currpos = emptypos[numdone];
- int prevplacedpos = numdone > 0 ? emptypos[numdone-1] : -1;
- int prevplacedheight = numdone > 0 ? P[prevplacedidx] : -1;
- int currheightidx = nxt[prevstatus][prevplacedidx][numdone][available];
- int height = P[currheightidx];
- placed[numdone] = height;
- int status;
- if (prevplacedpos == -1 || prevplacedpos + 2 < currpos) {
- status = height == V[currpos-1] ? 0 : (height < V[currpos-1] ? 1 : 2);
- } else if (prevplacedpos + 2 == currpos) {
- status = height == V[currpos-1] ? 0 : (height < V[currpos-1] ? 1 : 2);
- } else if (prevplacedpos + 1 == currpos) {
- status = height == prevplacedheight ? 0 : (height < prevplacedheight ? 1 : 2);
- }
- available &= ~(1 << currheightidx);
- prevstatus = status;
- prevplacedidx = currheightidx;
- numdone = numdone + 1;
- }
- // cout << ans << endl;
- int j = 0;
- for (int i = 0; i < N; ++i) {
- if (V[i] == 0) {
- cout << placed[j] << " ";
- ++j;
- } else {
- cout << V[i] << " ";
- }
- }
- }
- int main() {
- std::ios::sync_with_stdio(false);
- std::cin.tie(nullptr);
- #ifdef _DEBUG
- std::freopen("in.txt", "r", stdin);
- std::freopen("out.txt", "w", stdout);
- #endif
- Solve();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement