Untitled
unknown
plain_text
2 years ago
3.8 kB
5
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