CF EDU 114 D - The Strongest Build
阿新 • • 發佈:2022-05-15
D - The Strongest Build
BFS + 優先佇列 + 雜湊
將被 ban 掉的策略存到 map 裡,一開始將最大的策略放入優先佇列中,每次取隊首策略是否被 ban 掉了,如果沒有當前策略就是答案
如果被 ban 掉了,那放入比該策略小一點的策略,設隊首策略為 \(b_1,b_2,b_3,...,b_n\)
則分別放入 \(b_1-1,b_2,...,b_n\), \(b_1, b_2-1,...,b_n\) ... , \(b_1,b_2,...,b_n-1\)
再開一個 map 維護每個策略是否被放進過優先佇列中,如果被放進去過就不再放
極限情況下前 \(m\)
注意過載結構體小於號與結構體初始化的細節(把沒用到的地方都賦 0)
本題可用 map 來判斷某個策略是否被 ban 或已經放入佇列過,也可以用下述的雜湊函式表示策略
ull hs(vector<int> &vt)
{
ull ans = 0, p = 1;
for (auto i : vt)
{
ans += p * i;
p *= mod;
}
return ans;
}
#include <iostream> #include <cstring> #include <algorithm> #include <vector> #include <cmath> #include <tuple> #include <map> #include <queue> using namespace std; typedef long long ll; struct Node { ll val; int b[12]; bool operator<(const Node &x) const { if (val != x.val) return val < x.val; for (int i = 0; i < 12; i++) { if (b[i] != x.b[i]) return b[i] < x.b[i]; } return false; } }; map<Node, bool> st, ban; priority_queue<Node> heap; int n, m; const int N = 2e5 + 10; ll a[12][N]; int d[12]; void print(Node &x) { cout << x.val << endl; for (int i = 0; i < 12; i++) cout << x.b[i] << " "; cout << endl; } int main() { scanf("%d", &n); for (int i = 1; i <= n; i++) { int k; scanf("%d", &k); d[i] = k; for (int j = 1; j <= k; j++) scanf("%lld", &a[i][j]); } scanf("%d", &m); while(m--) { Node now; ll sum = 0; for (int i = 1; i <= n; i++) { scanf("%d", &now.b[i]); sum += a[i][now.b[i]]; } now.b[0] = 0; for (int i = n + 1; i < 12; i++) now.b[i] = 0; now.val = sum; // print(now); ban[now] = true; } Node first; first.val = 0; for (int i = 1; i <= n; i++) { first.b[i] = d[i]; first.val += a[i][d[i]]; } first.b[0] = 0; for (int i = n + 1; i < 12; i++) first.b[i] = 0; // print(first); heap.push(first); while(!heap.empty()) { auto fr = heap.top(); heap.pop(); if (!ban.count(fr)) { for (int i = 1; i <= n; i++) printf("%d ", fr.b[i]); printf("\n"); return 0; } for (int i = 1; i <= n; i++) { Node next = fr; int id = next.b[i]; if (id > 1) { next.val += a[i][id-1] - a[i][id]; next.b[i] = id - 1; if (st.count(next)) continue; st[next] = true; heap.push(next); } } } return 0; }