#include <bits/stdc++.h>
using namespace std;
using ll = long long;
/*
QUESTION IN SIMPLE WORDS
------------------------
We have a list of stations to process in a fixed order.
Each station has a workflow type.
There are 2 handlers:
- handler A
- handler B
For every station, we choose which handler will process it.
Cost rule:
- if that handler processed the same workflow type last time,
cost is shortTime[type]
- otherwise,
cost is longTime[type]
Goal:
Find the minimum total cost.
------------------------------------------------------------
BRUTE FORCE IDEA
------------------------------------------------------------
For every station, try both choices:
1) give it to A
2) give it to B
That gives 2^n possible assignments for n stations.
For each full assignment, simulate the total cost.
------------------------------------------------------------
WHY BRUTE FORCE IS TOO SLOW
------------------------------------------------------------
2^n grows very fast.
Even for around 30 stations, brute force is too expensive.
------------------------------------------------------------
OPTIMIZED IDEA
------------------------------------------------------------
At any step, to decide the next cost, we only need:
- the current station type
- last workflow type handled by A
- last workflow type handled by B
So we use DP.
DP state:
(lastA, lastB) -> minimum cost so far
That is enough because future cost depends only on these last values.
*/
ll minimumPrepTime(const vector<int>& stations,
const vector<ll>& shortTime,
const vector<ll>& longTime) {
// We pack (lastA, lastB) into one long long so it can be used as a map key.
auto makeKey = [&](int lastA, int lastB) -> long long {
return (1LL * (unsigned int)lastA << 32) | (unsigned int)lastB;
};
// Keep only the minimum cost for a state.
auto relax = [&](unordered_map<long long, ll>& mp, long long key, ll val) {
auto it = mp.find(key);
if (it == mp.end() || val < it->second) {
mp[key] = val;
}
};
unordered_map<long long, ll> dp, nextDp;
// Initially, nobody has processed anything.
// We use 0 as a dummy workflow type.
dp[makeKey(0, 0)] = 0;
for (int x : stations) {
nextDp.clear();
// Try all old states.
for (auto &it : dp) {
long long key = it.first;
ll curCost = it.second;
int lastA = (int)(key >> 32);
int lastB = (int)(key & 0xffffffffu);
// Option 1: current station goes to A
ll costIfAHandles = curCost + (lastA == x ? shortTime[x] : longTime[x]);
relax(nextDp, makeKey(x, lastB), costIfAHandles);
// Option 2: current station goes to B
ll costIfBHandles = curCost + (lastB == x ? shortTime[x] : longTime[x]);
relax(nextDp, makeKey(lastA, x), costIfBHandles);
}
dp.swap(nextDp);
}
// Final answer = minimum cost among all ending states
ll ans = LLONG_MAX;
for (auto &it : dp) ans = min(ans, it.second);
return ans;
}
int main() {
vector<int> stations = {1, 2, 1, 2, 2};
// Index = workflow type
vector<ll> shortTime = {0, 2, 3};
vector<ll> longTime = {0, 5, 7};
cout << minimumPrepTime(stations, shortTime, longTime) << '\n';
return 0;
}