제출 #1333987

#제출 시각아이디문제언어결과실행 시간메모리
1333987toast12Monster-Go (EGOI25_monstergo)C++20
100 / 100
1 ms344 KiB
#include <bits/stdc++.h>
using namespace std;

using ll = long long;

const int MAXN = 50;
const int INF = 1e9;

void generate(int n, int k, vector<vector<int>> &v) {
    // generate all subsets of n with length k
    vector<int> mask(n);
    for (int i = 0; i < k; i++) mask[i] = 1;
    reverse(mask.begin(), mask.end());
    do {
        for (int i = 0; i < n; i++) {
            if (mask[i]) {
                for (auto j : v[i]) cout << j << ' ';
            }
        }
        cout << '\n';
    }
    while (next_permutation(mask.begin(), mask.end()));
}

int main() {
    vector<vector<ll>> ncr(MAXN+1, vector<ll>(MAXN+1));
    for (int n = 0; n <= MAXN; n++) {
        ncr[n][0] = 1;
        for (int r = 1; r <= n; r++) ncr[n][r] = ncr[n-1][r-1]+ncr[n-1][r];
    }
    int sz[] = {1, 2, 3, 4, 6, 12};
    vector<int> list_cnt(1), cost(1), blocks_cnt(1), blocks_size(1);
    for (auto s : sz) {
        int blocks = 12/s;
        for (int n = blocks; n <= MAXN/s; n++) {
            if (ncr[n][blocks] <= MAXN) {
                list_cnt.push_back(ncr[n][blocks]);
                cost.push_back(n*s);
                blocks_cnt.push_back(n);
                blocks_size.push_back(s);
            }
        }
    }
    vector<vector<int>> dp(MAXN+1, vector<int>(list_cnt.size()+1, INF));
    // dp[i][j] stores the minimum total numbers needed to make i lists using the first j schemes
    fill(dp[0].begin(), dp[0].end(), 0);
    for (int i = 1; i <= MAXN; i++) {
        for (int j = 1; j < list_cnt.size(); j++) {
            dp[i][j] = min(dp[i][j], dp[i][j-1]);
            if (list_cnt[j] <= i) dp[i][j] = min(dp[i][j], dp[i-list_cnt[j]][j-1]+cost[j]);
        }
    }
    int N;
    cin >> N;
    vector<int> used;
    int i = N;
    for (int j = list_cnt.size()-1; j > 0; j--) {
        if (dp[i][j] < dp[i][j-1]) {
            used.push_back(j);
            i -= list_cnt[j];
        }
    }
    int offset = 0;
    for (auto i : used) {
        vector<vector<int>> v;
        for (int b = 0; b < blocks_cnt[i]; b++) {
            v.emplace_back();
            for (int j = 0; j < blocks_size[i]; j++) {
                v.back().push_back(offset);
                ++offset;
            }
        }
        generate(blocks_cnt[i], 12/blocks_size[i], v);
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...