Cod sursa(job #2611801)

Utilizator Alex_BubBuburuzan Alexandru Alex_Bub Data 7 mai 2020 16:41:55
Problema Cowfood Scor 76
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.59 kb
#include <fstream>

using namespace std;

ifstream fin("cowfood.in");
ofstream fout("cowfood.out");

const int MOD = 3210121, NMax = 20, KMax = 30, SMax = 10050;

int V[NMax + 5], N, K, S, A[NMax + 5][KMax + 5], C[SMax + 5][KMax + 5], Maxi[NMax + 5][KMax + 5], W[NMax], Sol;
bool Use[NMax + 5];

///Hint: PINEX, Stars and Bars, Hockey stick theorem

int Shrink(int x)
{
    if(x >= MOD)
        x -= MOD;

    return x;
}

void Process(int len, int Sum)
{
    if(len & 1)
        Sol = Shrink(Sol + C[S - Sum + K][K]);
    else
        Sol = Shrink(Sol + MOD - C[S - Sum + K][K]);
}

void BKT(int pos)
{
    for(int i = V[pos - 1] + 1; i <= N; i++)
    {
        if(Use[i]) continue;

        V[pos] = i;
        Use[i] = true;

        for(int k = 1; k <= K; k++)
        {
            Maxi[pos][k] = max(Maxi[pos - 1][k], A[i][k]);
            W[pos] += Maxi[pos][k];
        }
        Process(pos, W[pos]);

        if(pos < N)
           BKT(pos + 1);

        Use[i] = false;
        W[pos] = 0;
    }
}

void Precalc()
{
    for(int i = 0; i <= S + K; i++)
        C[i][0] = 1;

    for(int i = 1; i <= S + K; i++)
        for(int j = 1; j <= K; j++)
            C[i][j] = Shrink(C[i - 1][j] + C[i - 1][j - 1]);
}

int main()
{
    fin >> K >> S >> N;

    for(int i = 1; i <= N; i++)
        for(int j = 1; j <= K; j++)
            fin >> A[i][j];

    Precalc();
    BKT(1);

    int Total = Shrink(C[S + K][K] + MOD - (K * S + 1) % MOD);
    fout << Shrink(Total + MOD - Sol) << '\n';

    fin.close();
    fout.close();

    return 0;
}