Untitled
unknown
plain_text
2 years ago
3.8 kB
2
Indexable
#include <iostream> using namespace std; #define ll long long #define vi vector<int> #define pii pair<int, int> #define vii vector<pii> #define vli vector<pair<ll, int>> #define vl vector<long long> #define pb push_back const ll INF = 1e18; vi x, c, y, t; int n, m, k; vector <vi> vc; vi setTo; //вектор для перебора; в какое множество кладем элемент каждого типа vi numTo; vector <vli> opt;//для каждой маски храним вектор k наилучших пар (мин суммарное расстояние; цвет) ll ans; vector <vli> graph; void calc(int mask) { vli optc; vi cy; for (int i = 0; i < m; i++) { if (mask & (1 << i)) cy.pb(y[i]); } for (int clr = 0; clr < n; clr++) {//перебираем цвет //решаем задачу распределения шаров цвета clr по лункам типов из mask vector<vl> dp(m); vi cx = vc[clr]; for (int yy = 0; yy < m; yy++) { dp[yy].resize(n); for (int xx = 0; xx < n; xx++) { dp[yy][xx] = INF; if (xx) dp[yy][xx] = dp[yy][xx - 1]; if (xx) { if (yy) dp[yy][xx] = dp[yy - 1][xx - 1] + abs(cy[yy] - cx[xx]); else dp[yy][xx] = abs(cy[yy] - cx[xx]); } else { dp[yy][xx] = (yy ? INF : abs(cy[yy] - cx[xx])); } } } optc.pb({dp[m - 1][n - 1], clr}); } sort(optc.begin(), optc.end()); for (int i = 0; i < k; i++) opt[mask].pb(optc[i]); } pair<int, ll> minCostFlow() { } ll finalCalc() { vi setmasks; int sm = 0; for (int i = 0; i < k; i++) sm = max(sm, setTo[i]); sm++; setmasks.resize(sm); for (int i = 0; i < k; i++) { setmasks[setTo[i]] |= (1 << i); } map <int, int> vals; vi tmp; for (int mask : setmasks) { for ([cost, clr] : opt[mask]) { tmp.pb(clr); } } sort(tmp.begin(), tmp.end()); for (int i = 0; i < tmp.size(); i++) vals[tmp[i]] = i; graph.clear(); graph.resize(sm); for (int i = 0; i < sm; i++) { int mask = setmasks[i]; for (int [cost, clr] : opt[mask]) { graph[i].pb({vals[clr], cost]}); } } auto [flow, cost] = minCostFlow(); if (flow != sm) return INF; return cost; } //перебор разбиения множества типов на все возможные подмножества void go(int s, int i, bool was) { //на каком множестве стоим, на каком типе элементов стоим, непусто ли последнее открытое множество if (i >= k) { ans = min(ans, finalCalc()); return; } for (int is = 0; is <= s; is++) { setTo[i] = is; go(s, i + 1, was | (is == s)); } if (was) go(s + 1, i, 0); } void read() { cin >> n >> m >> k; x.resize(n); c.resize(n); y.resize(m); t.resize(m); for (int i = 0; i < n; i++) cin >> x[i]; for (int i = 0; i < n; i++) cin >> c[i]; for (int i = 0; i < n; i++) c[i]--; for (int i = 0; i < m; i++) cin >> y[i]; for (int i = 0; i < m; i++) cin >> t[i]; for (int i = 0; i < m; i++) t[i]--; } void solve() { read(); vc.resize(n); for (int i = 0; i < n; i++) vc[c[i]].pb(x[i]); opt.resize(1 << k); for (int tmask = 0; tmask < (1 << k); tmask++) {//перебираем маску типов, которые будут иметь один цвет calc(tmask); } ans = INF; setTo.resize(k) go(0, 0, 0); } int main() { solve(); return 0; }
Editor is loading...
Leave a Comment