Cod sursa(job #3254871)

Utilizator RusuRRusu Rares RusuR Data 9 noiembrie 2024 09:36:16
Problema Cowfood Scor 12
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.47 kb
#include <bits/stdc++.h>
#define int long long

const std :: string FILENAME = "cowfood";

std :: ifstream f (FILENAME + ".in");

std :: ofstream g (FILENAME + ".out");

const int NMAX = 55;

const int mod = 3210121;

int k;

int s;

int n;

long long ret;

int ans[NMAX];

int a[NMAX][NMAX];

int c[NMAX][NMAX];

int sp[NMAX][NMAX];

std :: stack <std :: vector <int>> mems;

void precalc(int n)
{
    c[1][0] = c[1][1] = 1;

    for(int i = 2; i <= n; i ++)
    {
        c[i][0] = 1;

        for(int j = 1; j <= i; j ++)
        {
            c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod;
        }
    }

    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= n; j ++)
        {
            sp[i][j] = (sp[i][j - 1] + c[j][i]) % mod;
        }
    }
}

void pinex(int cnt, std :: vector <int> aux)//aici se intampla magia
{
    int semn = (cnt % 2 == 0) ? -1 : 1;

    //cate sunt mai mari decat aux care este o combinatie de unul sau mai multe experimente

    //fix S

    int sum = 0;

    for(int & i : aux)
    {
        sum += i;
    }

    int up = s - sum;

    if(up < 0)
    {
        return ;
    }

    // am stars and bars cu obiecte <= up si cutii = k __ C(up, k), cat timp up >= k

    //deci imi trebuie sp dupa k- uri

    int _n = up;

    _n += k - 1;

    int _k = k;

    _k --;

    ret += semn * sp[_k][_n];

    ret += mod;

    ret %= mod;
}

void bkt(int poz)
{
    if(poz == 1)
    {
        for(int i = 1; i <= n; i ++)
        {
            std :: vector <int> aux;

            ans[poz] = i;

            for(int j = 1; j <= k; j ++)
            {
                aux.push_back(a[i][j]);
            }

            pinex(poz, aux);

            mems.push(aux);

            bkt(poz + 1);

            mems.pop();
        }
    }
    else
    {
        for(int i = ans[poz - 1] + 1; i <= n; i ++)
        {
            std :: vector <int> aux = mems.top();

            ans[poz] = i;

            for(int j = 1; j <= k; j ++)
            {
                aux[j - 1] = std :: max(aux[j - 1], a[i][j]);
            }

            pinex(poz, aux);

            mems.push(aux);

            bkt(poz + 1);

            mems.pop();
        }
    }
}

int32_t main()
{

    f >> k >> s >> n;

    precalc(50);

    for(int i = 1; i <= n; i ++)
    {
        for(int j = 1; j <= k; j ++)
        {
            f >> a[i][j];
        }
    }

    bkt(1);

    int _n = s;

    _n += k - 1;

    int _k = k;

    _k --;

    g << (1ll * sp[_k][_n] - 1 - k * s - ret) % mod;

    return 0;
}