| # | 제출 시각 | 아이디 | 문제 | 언어 | 결과 | 실행 시간 | 메모리 | 
|---|---|---|---|---|---|---|---|
| 1122745 | AnhPham | Wall (CEOI14_wall) | C++20 | 0 ms | 0 KiB | 
#include <bits/stdc++.h>
using namespace std;
#define int     long long
#define sz(v)   (int)(v).size()
#define all(v)  (v).begin(), (v).end()
const   int     MOD = (int)1e9 + 7;
const   int     INF = (int)4e18 + 18;
void solve();
int32_t main() {
#define CODE ""
    if (fopen(CODE".inp", "r"))
        freopen(CODE".inp", "r", stdin), freopen(CODE".out", "w", stdout);
    cin.tie(nullptr), cout.tie(nullptr) -> sync_with_stdio(false);
    int testcases = 1;
#define multitest 0
    if (multitest) { cin >> testcases; } for (; testcases--;) { solve(); }
}
/** [Pham Hung Anh - 12I - Tran Hung Dao High School for Gifted Student] **/
/**                            The Last Dance                            **/
const int mxN = 404;
int N, M;
int A[mxN][mxN];
int ver[mxN][mxN], hor[mxN][mxN];
namespace sub1 {
    bool check_condition() {
        int cnt = 0;
        for (int i = 1; i <= N; ++i)
            for (int j = 1; j <= M; ++j)
                cnt += A[i][j] == 1;
        return cnt <= 10 && N <= 40 && M <= 40;
    }
    int mask_ver[44][44];
    int nodes, id[44][44][1 << 11];
    vector <pair <int, int>> adj[44 * 44];
    int dst[mxN * mxN * (1 << 11)];
    void add_edge(int u, int v, int c) {
        adj[u].push_back({ c, v });
        adj[v].push_back({ c, u });
    }
    void solve() {
        vector <pair <int, int>> points;
        for (int i = 1; i <= N; ++i)
            for (int j = 1; j <= M; ++j)
                if (A[i][j] == 1)
                    points.push_back({ i, j });
        for (int i = 0; i < N; ++i)
            for (int j = 0; j <= M; ++j)
                for (int k = 0; k < sz(points); ++k)
                    if (points[k].first == i + 1 && points[k].second <= j)
                        mask_ver[i][j] |= 1 << k;
        for (int i = 0; i <= N; ++i)
            for (int j= 0; j <= M; ++j)
                for (int mask = 0; mask < (1 << sz(points)); ++mask)
                    id[i][j][mask] = ++nodes;
        for (int i = 0; i <= N; ++i)
            for (int j = 0; j <= M; ++j)
                for (int mask = 0; mask < (1 << sz(points)); ++mask) {
                    if (i < N)
                        add_edge(id[i][j][mask], id[i + 1][j][mask ^ mask_ver[i][j]], ver[i][j]);
                    if (j < N)
                        add_edge(id[i][j][mask], id[i][j + 1][mask], hor[i][j]);
                }
        for (int i = 1; i <= nodes; ++i)
            dst[i] = 1ll << 60;
        priority_queue <pair <int, int>> pq;
        pq.push ({ dst[id[0][0][0]] = 0, id[0][0][0] });
        while (sz(pq)) {
            auto [du, u] = pq.top(); pq.pop();
            if (dst[u] != -du)
                continue;
            for (auto [c, v] : adj[u])
                if (dst[v] > dst[u] + c) {
                    dst[v] = dst[u] + c;
                    pq.push({ -dst[v], v });
                }
        }
        cout << dst[id[0][0][(1 << sz(points)) - 1]] << '\n';
    }
}
void solve() {
    cin >> N >> M;
    for (int i = 1; i <= N; ++i)
        for (int j = 1; j <= M; ++j)
            cin >> A[i][j];
    for (int i = 0; i < N; ++i)
        for (int j = 0; j <= M; ++j)
            cin >> ver[i][j];
    for (int i = 0; i <= N; ++i)
        for (int j = 0; j < M; ++j)
            cin >> hor[i][j];
    if (sub1 :: check_condition())
        sub1 :: solve();
}
