123792024-12-15 01:38:06kukkermanFestés (50 pont)cpp17Accepted 50/50458ms12092 KiB
#include <iostream>
#include <array>
#include <vector>
#include <algorithm>
#include <limits>

using SorKoltsegek = std::vector<uint64_t>;
using FestesKoltsegek = std::vector<uint64_t>;
using OszlopKoltsegek = std::vector<FestesKoltsegek>;

using Lefedesek = std::array<int, 21>;
using KifestesLefedesek = std::array<Lefedesek, 16>;
using OsszesLefedes = std::array<KifestesLefedesek, 4>;

constexpr void osszes_lefedes_k(int sorok_szama, Lefedesek &lefedesek, int &k, int kifestendo_sorok, int elso_sor = 0, int elso_festes_index = 0, int akt_lefedes = 0) {
    int elso_kifestendo = 0;
    for (elso_kifestendo = elso_sor; elso_kifestendo < sorok_szama && (kifestendo_sorok & (1 << elso_kifestendo)) == 0; elso_kifestendo++) {}

    if (elso_kifestendo == sorok_szama) {
        lefedesek[k++] = akt_lefedes;
        return;
    }

    const int kov_sor_elso_index = elso_festes_index + sorok_szama - elso_sor;
    for (int honnan = elso_sor; honnan <= elso_kifestendo; honnan++) {
        for (int hova = elso_kifestendo; hova < sorok_szama; hova++) {
            const int maszk = ((1 << (hova + 1)) - 1) ^ ((1 << honnan) - 1);
            const int festes_bit = 1 << (elso_festes_index + hova - honnan);

            osszes_lefedes_k(sorok_szama,
                             lefedesek,
                             k,
                             kifestendo_sorok & ~maszk,
                             elso_sor + 1,
                             kov_sor_elso_index,
                             akt_lefedes | festes_bit);
        }

        elso_festes_index += sorok_szama - honnan;
    }
}

constexpr OsszesLefedes osszes_lefedes_k() {
    OsszesLefedes l{};

    for (int sorok_szama = 1; sorok_szama <= 4; sorok_szama++) {
        const int osszes_kifestes = 1 << sorok_szama;
        for (int kifestendo_sorok = 0; kifestendo_sorok < osszes_kifestes; kifestendo_sorok++) {
            auto &s = l[sorok_szama - 1][kifestendo_sorok];
            int k = 0;
            osszes_lefedes_k(sorok_szama, s, k, kifestendo_sorok);
            s[k] = -1;
        }
    }

    return l;
}

static constexpr OsszesLefedes osszes_lefedes = osszes_lefedes_k();

void beolvas(std::istream &be, SorKoltsegek &r, OszlopKoltsegek &o) {
    int n, m;
    be >> n >> m;

    r.resize(n);
    for (auto &akt_sor : r) {
        be >> akt_sor;
    }

    const int festesek_db = n * (n + 1) / 2;
    o.resize(m);
    for (auto &akt_oszlop : o) {
        akt_oszlop.resize(festesek_db);
        for (auto &f: akt_oszlop) {
            be >> f;
        }
    }
}

uint64_t min_oszlop_koltseg(int sorok_szama, int kifestendo_sorok, const FestesKoltsegek &c) {
    uint64_t min_koltseg = std::numeric_limits<uint64_t>::max();

    const auto &lefedesek = osszes_lefedes[sorok_szama - 1][kifestendo_sorok];
    for (int i = 0; lefedesek[i] != -1; i++) {
        int akt_lefedes = lefedesek[i];
        int akt_festes = 0;
        uint64_t akt_koltseg = 0;
        while (akt_lefedes != 0) {
            if (akt_lefedes & 1) {
                akt_koltseg += c[akt_festes];
            }
            akt_lefedes >>= 1;
            akt_festes++;
        }

        min_koltseg = std::min(min_koltseg, akt_koltseg);
    }

    return min_koltseg;
}

void feldolgoz(const SorKoltsegek &r, const OszlopKoltsegek &c) {
    const int sorok_szama = static_cast<int>(r.size());
    const int oszlopok_szama = static_cast<int>(c.size());
    const int max_sor_halmaz = (1 << sorok_szama);

    auto min_koltseg = std::numeric_limits<uint64_t>::max();
    for (int kifestendo_sorok = 0; kifestendo_sorok < max_sor_halmaz; kifestendo_sorok++) {
        uint64_t akt_koltseg = 0u;
        for (int sor = 0; sor < sorok_szama; sor++) {
            if ((kifestendo_sorok & (1 << sor)) == 0) {
                akt_koltseg += r[sor];
            }
        }

        for (int akt_oszlop = 0; akt_oszlop < oszlopok_szama; akt_oszlop++) {
            akt_koltseg += min_oszlop_koltseg(sorok_szama, kifestendo_sorok, c[akt_oszlop]);
        }
        min_koltseg = std::min(min_koltseg, akt_koltseg);
    }

    std::cout << min_koltseg << '\n';
}

int main() {
    SorKoltsegek r;
    OszlopKoltsegek c;
    beolvas(std::cin, r, c);

    feldolgoz(r, c);

    return 0;
}
SubtaskSumTestVerdictTimeMemory
base50/50
1Accepted0/01ms320 KiB
2Accepted0/01ms508 KiB
3Accepted2/2216ms9012 KiB
4Accepted2/21ms320 KiB
5Accepted3/34ms320 KiB
6Accepted2/237ms1584 KiB
7Accepted2/2416ms11912 KiB
8Accepted2/2414ms11988 KiB
9Accepted2/2416ms11900 KiB
10Accepted2/2416ms12092 KiB
11Accepted2/2416ms12088 KiB
12Accepted2/2381ms11064 KiB
13Accepted2/2404ms11064 KiB
14Accepted2/2100ms5688 KiB
15Accepted3/3104ms5692 KiB
16Accepted3/3187ms9016 KiB
17Accepted2/2187ms9016 KiB
18Accepted3/3184ms9016 KiB
19Accepted2/2356ms10876 KiB
20Accepted2/2384ms11320 KiB
21Accepted2/2405ms11832 KiB
22Accepted2/2412ms12088 KiB
23Accepted2/2412ms12088 KiB
24Accepted2/2398ms12088 KiB
25Accepted2/2458ms12088 KiB