Submission details
Task:Yhdistelmät
Sender:Metabolix
Submission time:2025-11-29 22:06:37 +0200
Language:C++ (C++20)
Status:READY
Result:46
Feedback
groupverdictscore
#10
#2ACCEPTED17
#3ACCEPTED29
#40
Test results
testverdicttimegroup
#1ACCEPTED0.00 s1, 2, 3, 4details
#2ACCEPTED0.00 s1, 3, 4details
#3ACCEPTED0.00 s1, 4details
#4ACCEPTED0.00 s1, 4details
#50.00 s1, 4details
#6ACCEPTED0.01 s1, 4details
#7ACCEPTED0.01 s1, 4details
#8ACCEPTED0.00 s1, 4details
#9ACCEPTED0.00 s1, 4details
#100.00 s1, 4details
#11ACCEPTED0.00 s2, 3, 4details
#12ACCEPTED0.00 s3, 4details
#130.00 s4details
#140.02 s4details
#150.06 s4details
#16ACCEPTED0.10 s4details
#17ACCEPTED0.10 s4details
#18ACCEPTED0.00 s1, 2, 3, 4details
#19ACCEPTED0.00 s1, 2, 3, 4details
#20ACCEPTED0.15 s4details
#21ACCEPTED0.00 s4details

Compiler report

input/code.cpp: In function 'void ratkaise(std::vector<int>, std::unordered_map<std::bitset<128>, int>, bool)':
input/code.cpp:142:10: warning: variable 'purkkaratkaisu_joka_toimii_d2' set but not used [-Wunused-but-set-variable]
  142 |     auto purkkaratkaisu_joka_toimii_d2 = [&]() {
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Code

#include <bits/stdc++.h>
using namespace std;

typedef bitset<128> bits_t;

void lue_syote(vector<int>& hinnat, unordered_map<bits_t, int>& palkkiot) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    cin >> n >> m;
    hinnat.resize(n);
    for (int i = 0; i < n; ++i) {
        cin >> hinnat[i];
    }

    palkkiot.clear();
    for (int i = 0; i < m; ++i) {
        bits_t yhdistelmä;
        int k, x;
        cin >> k >> x;
        for (int j = 0; j < k; ++j) {
            int indeksi;
            cin >> indeksi;
            indeksi -= 1;
            yhdistelmä.set(indeksi);
        }
        palkkiot[yhdistelmä] += x;
    }
}

void luo_syote(vector<int>& hinnat, unordered_map<bits_t, int>& palkkiot, int seed) {
    srand(seed);
    int n = 8, m = n + rand() % 20 + 1;
    hinnat.resize(n);
    for (int i = 0; i < n; ++i) {
        hinnat[i] = rand() % 1000 + 1;
    }

    palkkiot.clear();
    for (int i = 0; i < m; ++i) {
        bits_t yhdistelmä;
        int k = rand() % n + 1;
        for (int j = 0; j < k; ++j) {
            int indeksi = rand() % n;
            yhdistelmä.set(indeksi);
        }
        int x = rand() % 5000 + 1;
        palkkiot[yhdistelmä] += x;
    }
}

void ratkaise(vector<int> hinnat, unordered_map<bits_t, int> palkkiot, bool testi) {
    int n = hinnat.size();

    for (int i = 0; i < n; ++i) {
        int paras_arvo = -hinnat[i];
        for (const auto& [yhdistelmä, palkkio] : palkkiot) {
            if (yhdistelmä.test(i)) {
                paras_arvo += palkkio;
            }
        }
        if (paras_arvo <= 0) {
            unordered_set<bits_t> poistettavat;
            for (const auto& [yhdistelmä, palkkio] : palkkiot) {
                if (yhdistelmä.test(i)) {
                    poistettavat.insert(yhdistelmä);
                }
            }
            for (const auto& yhdistelmä : poistettavat) {
                palkkiot.erase(yhdistelmä);
            }
        }
    }

    int d = 0;
    for (const auto& [yhdistelmä, _] : palkkiot) {
        d = max(d, (int) yhdistelmä.count());
    }

    auto laske_arvo = [&](bits_t yhdistelmä) {
        int arvo = 0;
        for (int i = 0; i < n; ++i) {
            if (yhdistelmä.test(i)) {
                arvo -= hinnat[i];
            }
        }
        for (const auto& [palkkio_yhdistelmä, palkkio] : palkkiot) {
            if ((yhdistelmä & palkkio_yhdistelmä) == palkkio_yhdistelmä) {
                arvo += palkkio;
            }
        }
        return arvo;
    };

    auto ilmoita_tulos = [&](bits_t yhdistelmä) {
        cout << laske_arvo(yhdistelmä) << "\n";
        cout << yhdistelmä.count() << "\n";
        for (int i = 0; i < n; ++i) {
            if (yhdistelmä.test(i)) {
                cout << (i + 1) << " ";
            }
        }
        cout << endl;
    };

    bits_t selvästi_kannattavat;
    int selvästi_kannattavat_arvo = 0;
    for (int i = 0; i < n; ++i) {
        bool muutos = false;
        for (const auto& [yhdistelmä, palkkio] : palkkiot) {
            bits_t uusi = selvästi_kannattavat | yhdistelmä;
            if (uusi == selvästi_kannattavat) {
                continue;
            }
            int uusi_arvo = laske_arvo(uusi);
            if (uusi_arvo >= selvästi_kannattavat_arvo) {
                muutos = true;
                selvästi_kannattavat = uusi;
                selvästi_kannattavat_arvo = uusi_arvo;
            }
        }
        if (!muutos) {
            break;
        }
    }

    auto pieni_tapaus = [&]() {
        bits_t paras_yhdistelmä = 0;
        int paras_arvo = 0;
        for (uint32_t yhdistelmä = 0; yhdistelmä < (uint32_t(1) << n); ++yhdistelmä) {
            bits_t bs_yhdistelmä(yhdistelmä);
            int arvo = laske_arvo(bs_yhdistelmä);
            if (arvo > paras_arvo) {
                paras_yhdistelmä = bs_yhdistelmä;
                paras_arvo = arvo;
            }
        }
        return paras_yhdistelmä;
    };

    auto purkkaratkaisu_joka_toimii_d2 = [&]() {
        bits_t paras_yhdistelmä = selvästi_kannattavat;
        int paras_arvo = laske_arvo(paras_yhdistelmä);
        for (const auto& [yhdistelmä, palkkio] : palkkiot) {
            bits_t uusi = selvästi_kannattavat | yhdistelmä;
            int uusi_arvo = laske_arvo(uusi);
            unordered_set<bits_t> kokeilematta;
            for (const auto& [toinen_yhdistelmä, _] : palkkiot) {
                if ((uusi | toinen_yhdistelmä) != uusi) {
                    kokeilematta.insert(toinen_yhdistelmä);
                }
            }
            while (kokeilematta.size()) {
                bits_t toinen_yhdistelmä = *kokeilematta.begin();
                kokeilematta.erase(kokeilematta.begin());
                bits_t uusi2 = uusi | toinen_yhdistelmä;
                int uusi2_arvo = laske_arvo(uusi2);
                if (uusi2_arvo > uusi_arvo) {
                    uusi = uusi2;
                    uusi_arvo = uusi2_arvo;
                }
            }
            if (uusi_arvo > paras_arvo) {
                paras_yhdistelmä = uusi;
                paras_arvo = uusi_arvo;
            }
        }
        return paras_yhdistelmä;
    };

    auto purkkaratkaisu = [&]() {
        bits_t paras_yhdistelmä = selvästi_kannattavat;
        int paras_arvo = laske_arvo(paras_yhdistelmä);
        auto paranna = [&](bits_t uusi) {
            int uusi_arvo = laske_arvo(uusi);
            if (uusi_arvo > paras_arvo) {
                paras_yhdistelmä = uusi;
                paras_arvo = uusi_arvo;
            }
        };
        for (auto i1 = palkkiot.begin(); i1 != palkkiot.end(); ++i1) {
            bits_t uusi1 = selvästi_kannattavat | i1->first;
            if (uusi1 == selvästi_kannattavat) {
                continue;
            }
            paranna(uusi1);
            for (auto i2 = next(i1); i2 != palkkiot.end(); ++i2) {
                bits_t uusi2 = uusi1 | i2->first;
                if (uusi2 == uusi1) {
                    continue;
                }
                paranna(uusi2);
                for (auto i3 = next(i2); i3 != palkkiot.end(); ++i3) {
                    bits_t uusi3 = uusi2 | i3->first;
                    if (uusi3 == uusi2) {
                        continue;
                    }
                    paranna(uusi3);
                }
            }
        }
        return paras_yhdistelmä;
    };

    bits_t paras_yhdistelmä;
    bits_t oikea_yhdistelmä;
    if (testi) {
        oikea_yhdistelmä = pieni_tapaus();
        paras_yhdistelmä = purkkaratkaisu();
        if (paras_yhdistelmä != oikea_yhdistelmä) {
            ilmoita_tulos(oikea_yhdistelmä);
            cout << "----\n";
            ilmoita_tulos(paras_yhdistelmä);
            throw runtime_error("VIRHE");
        }
        return;
    } else if (d == 1) {
        paras_yhdistelmä = selvästi_kannattavat;
#if 0
    } else if (n <= 20) {
        paras_yhdistelmä = pieni_tapaus();
    } else if (d == 2) {
        paras_yhdistelmä = purkkaratkaisu_joka_toimii_d2();
#endif
    } else {
        paras_yhdistelmä = purkkaratkaisu();
    }
    ilmoita_tulos(paras_yhdistelmä);
}

int main(int argc, char** argv) {
    vector<int> hinnat;
    unordered_map<bits_t, int> palkkiot;
    if (argc == 2 && string(argv[1]) == "kotitesti") {
        lue_syote(hinnat, palkkiot);
        ratkaise(hinnat, palkkiot, true);
        for (int seed = 1; seed <= 1000; ++seed) {
            cerr << "Testi " << seed << "\n";
            luo_syote(hinnat, palkkiot, seed);
            ratkaise(hinnat, palkkiot, true);
        }
    } else {
        lue_syote(hinnat, palkkiot);
        ratkaise(hinnat, palkkiot, false);
    }
}

Test details

Test 1

Group: 1, 2, 3, 4

Verdict: ACCEPTED

input
20 20
80 69 91 47 74 75 94 22 100 43...

correct output
446
11
2 3 5 8 10 13 14 15 17 19 20 

user output
446
11
2 3 5 8 10 13 14 15 17 19 20 

Test 2

Group: 1, 3, 4

Verdict: ACCEPTED

input
20 20
5 42 7 18 55 64 64 83 73 44 22...

correct output
425
11
1 2 3 4 7 10 13 16 18 19 20 

user output
425
11
1 2 3 4 7 10 13 16 18 19 20 

Test 3

Group: 1, 4

Verdict: ACCEPTED

input
20 20
30 98 55 69 40 3 95 12 64 56 3...

correct output
284
8
1 3 8 10 15 16 18 19 

user output
284
8
1 3 8 10 15 16 18 19 

Test 4

Group: 1, 4

Verdict: ACCEPTED

input
20 20
11 44 58 8 16 52 20 43 24 31 4...

correct output
348
10
2 4 5 7 11 13 15 16 18 20 

user output
348
10
2 4 5 7 11 13 15 16 18 20 

Test 5

Group: 1, 4

Verdict:

input
20 20
53 44 5 37 88 36 81 47 85 97 3...

correct output
119
13
1 2 4 8 10 11 13 14 16 17 18 1...

user output
105
9
1 2 4 10 13 14 16 17 18 

Test 6

Group: 1, 4

Verdict: ACCEPTED

input
20 20
20 27 75 94 48 62 37 55 49 67 ...

correct output
478
11
1 2 5 7 10 12 13 15 16 17 18 

user output
478
11
1 2 5 7 10 12 13 15 16 17 18 

Test 7

Group: 1, 4

Verdict: ACCEPTED

input
20 20
32 28 67 72 32 76 53 30 47 67 ...

correct output
215
10
2 4 5 7 8 9 11 13 16 20 

user output
215
10
2 4 5 7 8 9 11 13 16 20 

Test 8

Group: 1, 4

Verdict: ACCEPTED

input
20 20
39 72 74 79 49 45 73 44 37 4 7...

correct output
185
13
1 3 5 6 7 8 10 13 14 16 17 18 ...

user output
185
11
1 3 7 8 10 13 14 16 17 18 20 

Test 9

Group: 1, 4

Verdict: ACCEPTED

input
20 20
41 56 65 78 2 13 17 42 83 76 9...

correct output
95
11
2 4 5 6 7 8 13 14 17 18 19 

user output
95
11
2 4 5 6 7 8 13 14 17 18 19 

Test 10

Group: 1, 4

Verdict:

input
20 20
43 1 20 61 25 46 2 18 36 1 85 ...

correct output
111
8
1 2 3 7 8 10 16 19 

user output
110
12
1 2 3 7 8 9 10 12 16 17 19 20 

Test 11

Group: 2, 3, 4

Verdict: ACCEPTED

input
100 100
992248 852673 366775 737068 56...

correct output
30642743
46
3 5 6 9 11 12 15 16 17 18 21 2...

user output
30642743
46
3 5 6 9 11 12 15 16 17 18 21 2...

Test 12

Group: 3, 4

Verdict: ACCEPTED

input
100 100
153790 361741 45017 47184 9422...

correct output
16529629
39
2 3 4 5 10 12 14 17 24 25 26 3...

user output
16529629
39
2 3 4 5 10 12 14 17 24 25 26 3...

Test 13

Group: 4

Verdict:

input
100 100
186797 446409 957173 150683 17...

correct output
14928280
62
1 2 8 9 10 11 12 14 15 16 17 2...

user output
14475875
54
2 8 9 10 11 14 15 16 17 20 21 ...

Test 14

Group: 4

Verdict:

input
100 100
343213 582494 707357 104682 66...

correct output
11308944
72
1 3 4 5 6 7 8 9 10 11 12 13 14...

user output
8149432
43
3 4 5 7 8 10 11 14 26 29 30 33...

Test 15

Group: 4

Verdict:

input
100 100
922546 12088 805566 351521 644...

correct output
3311952
10
14 17 26 29 64 65 70 76 83 95 

user output
3020035
12
2 14 17 26 29 33 64 65 70 76 8...

Test 16

Group: 4

Verdict: ACCEPTED

input
100 100
923042 35929 531316 587665 845...

correct output
519209
6
2 18 45 61 64 86 

user output
519209
6
2 18 45 61 64 86 

Test 17

Group: 4

Verdict: ACCEPTED

input
100 100
493725 218022 417464 531537 83...

correct output
1255541
11
16 19 24 29 30 50 60 62 67 74 ...

user output
1255541
11
16 19 24 29 30 50 60 62 67 74 ...

Test 18

Group: 1, 2, 3, 4

Verdict: ACCEPTED

input
1 1
2
1 1
1

correct output
0
0

user output
0
0

Test 19

Group: 1, 2, 3, 4

Verdict: ACCEPTED

input
1 1
1
1 2
1

correct output
1
1

user output
1
1

Test 20

Group: 4

Verdict: ACCEPTED

input
100 100
1000000 1000000 1000000 100000...

correct output
0
100
1 2 3 4 5 6 7 8 9 10 11 12 13 ...

user output
0
0

Test 21

Group: 4

Verdict: ACCEPTED

input
100 100
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ...

correct output
99999900
100
1 2 3 4 5 6 7 8 9 10 11 12 13 ...

user output
99999900
100
1 2 3 4 5 6 7 8 9 10 11 12 13 ...